mirror of
https://github.com/ossrs/srs.git
synced 2025-02-14 20:31:56 +00:00
support decode user control message. response ping automatically
This commit is contained in:
parent
0a92faf2e3
commit
9da31de1c1
3 changed files with 142 additions and 34 deletions
|
@ -449,6 +449,47 @@ int SrsProtocol::send_message(ISrsMessage* msg)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsProtocol::response_acknowledgement_message()
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||||
|
SrsAcknowledgementPacket* pkt = new SrsAcknowledgementPacket();
|
||||||
|
|
||||||
|
in_ack_size.acked_size = pkt->sequence_number = skt->get_recv_bytes();
|
||||||
|
msg->set_packet(pkt, 0);
|
||||||
|
|
||||||
|
if ((ret = send_message(msg)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("send acknowledgement failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_verbose("send acknowledgement success.");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsProtocol::response_ping_message(int32_t timestamp)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
srs_trace("get a ping request, response it. timestamp=%d", timestamp);
|
||||||
|
|
||||||
|
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||||
|
SrsUserControlPacket* pkt = new SrsUserControlPacket();
|
||||||
|
|
||||||
|
pkt->event_type = SrcPCUCPingResponse;
|
||||||
|
pkt->event_data = timestamp;
|
||||||
|
msg->set_packet(pkt, 0);
|
||||||
|
|
||||||
|
if ((ret = send_message(msg)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("send ping response failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_verbose("send ping response success.");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int SrsProtocol::on_recv_message(SrsCommonMessage* msg)
|
int SrsProtocol::on_recv_message(SrsCommonMessage* msg)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -457,21 +498,14 @@ int SrsProtocol::on_recv_message(SrsCommonMessage* msg)
|
||||||
|
|
||||||
// acknowledgement
|
// acknowledgement
|
||||||
if (skt->get_recv_bytes() - in_ack_size.acked_size > in_ack_size.ack_window_size) {
|
if (skt->get_recv_bytes() - in_ack_size.acked_size > in_ack_size.ack_window_size) {
|
||||||
SrsCommonMessage* ack = new SrsCommonMessage();
|
if ((ret = response_acknowledgement_message()) != ERROR_SUCCESS) {
|
||||||
SrsAcknowledgementPacket* pkt = new SrsAcknowledgementPacket();
|
|
||||||
|
|
||||||
in_ack_size.acked_size = pkt->sequence_number = skt->get_recv_bytes();
|
|
||||||
ack->set_packet(pkt, 0);
|
|
||||||
|
|
||||||
if ((ret = send_message(ack)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("send acknowledgement failed. ret=%d", ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
srs_verbose("send acknowledgement success.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (msg->header.message_type) {
|
switch (msg->header.message_type) {
|
||||||
case RTMP_MSG_SetChunkSize:
|
case RTMP_MSG_SetChunkSize:
|
||||||
|
case RTMP_MSG_UserControlMessage:
|
||||||
case RTMP_MSG_WindowAcknowledgementSize:
|
case RTMP_MSG_WindowAcknowledgementSize:
|
||||||
if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {
|
if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {
|
||||||
srs_error("decode packet from message payload failed. ret=%d", ret);
|
srs_error("decode packet from message payload failed. ret=%d", ret);
|
||||||
|
@ -503,6 +537,20 @@ int SrsProtocol::on_recv_message(SrsCommonMessage* msg)
|
||||||
srs_trace("set input chunk size to %d", pkt->chunk_size);
|
srs_trace("set input chunk size to %d", pkt->chunk_size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case RTMP_MSG_UserControlMessage: {
|
||||||
|
SrsUserControlPacket* pkt = dynamic_cast<SrsUserControlPacket*>(msg->get_packet());
|
||||||
|
srs_assert(pkt != NULL);
|
||||||
|
|
||||||
|
if (pkt->event_type == SrcPCUCSetBufferLength) {
|
||||||
|
srs_trace("ignored. set buffer length to %d", pkt->extra_data);
|
||||||
|
}
|
||||||
|
if (pkt->event_type == SrcPCUCPingRequest) {
|
||||||
|
if ((ret = response_ping_message(pkt->event_data)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -963,6 +1011,11 @@ bool SrsMessageHeader::is_set_chunk_size()
|
||||||
return message_type == RTMP_MSG_SetChunkSize;
|
return message_type == RTMP_MSG_SetChunkSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsMessageHeader::is_user_control_message()
|
||||||
|
{
|
||||||
|
return message_type == RTMP_MSG_UserControlMessage;
|
||||||
|
}
|
||||||
|
|
||||||
SrsChunkStream::SrsChunkStream(int _cid)
|
SrsChunkStream::SrsChunkStream(int _cid)
|
||||||
{
|
{
|
||||||
fmt = 0;
|
fmt = 0;
|
||||||
|
@ -1098,6 +1151,10 @@ int SrsCommonMessage::decode_packet()
|
||||||
srs_trace("drop the AMF0/AMF3 command message, command_name=%s", command.c_str());
|
srs_trace("drop the AMF0/AMF3 command message, command_name=%s", command.c_str());
|
||||||
packet = new SrsPacket();
|
packet = new SrsPacket();
|
||||||
return ret;
|
return ret;
|
||||||
|
} else if(header.is_user_control_message()) {
|
||||||
|
srs_verbose("start to decode user control message.");
|
||||||
|
packet = new SrsUserControlPacket();
|
||||||
|
return packet->decode(stream);
|
||||||
} else if(header.is_window_ackledgement_size()) {
|
} else if(header.is_window_ackledgement_size()) {
|
||||||
srs_verbose("start to decode set ack window size message.");
|
srs_verbose("start to decode set ack window size message.");
|
||||||
packet = new SrsSetWindowAckSizePacket();
|
packet = new SrsSetWindowAckSizePacket();
|
||||||
|
@ -2396,45 +2453,86 @@ int SrsSetPeerBandwidthPacket::encode_packet(SrsStream* stream)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsPCUC4BytesPacket::SrsPCUC4BytesPacket()
|
SrsUserControlPacket::SrsUserControlPacket()
|
||||||
{
|
{
|
||||||
event_type = 0;
|
event_type = 0;
|
||||||
event_data = 0;
|
event_data = 0;
|
||||||
|
extra_data = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsPCUC4BytesPacket::~SrsPCUC4BytesPacket()
|
SrsUserControlPacket::~SrsUserControlPacket()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsPCUC4BytesPacket::get_perfer_cid()
|
int SrsUserControlPacket::decode(SrsStream* stream)
|
||||||
{
|
|
||||||
return RTMP_CID_ProtocolControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsPCUC4BytesPacket::get_message_type()
|
|
||||||
{
|
|
||||||
return RTMP_MSG_UserControlMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsPCUC4BytesPacket::get_size()
|
|
||||||
{
|
|
||||||
return 2 + 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsPCUC4BytesPacket::encode_packet(SrsStream* stream)
|
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
if (!stream->require(6)) {
|
if (!stream->require(6)) {
|
||||||
|
ret = ERROR_RTMP_MESSAGE_DECODE;
|
||||||
|
srs_error("decode user control failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_type = stream->read_2bytes();
|
||||||
|
event_data = stream->read_4bytes();
|
||||||
|
|
||||||
|
if (event_type == SrcPCUCSetBufferLength) {
|
||||||
|
if (!stream->require(2)) {
|
||||||
|
ret = ERROR_RTMP_MESSAGE_ENCODE;
|
||||||
|
srs_error("decode user control packet failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
extra_data = stream->read_4bytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
srs_info("decode user control success. "
|
||||||
|
"event_type=%d, event_data=%d, extra_data=%d",
|
||||||
|
event_type, event_data, extra_data);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsUserControlPacket::get_perfer_cid()
|
||||||
|
{
|
||||||
|
return RTMP_CID_ProtocolControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsUserControlPacket::get_message_type()
|
||||||
|
{
|
||||||
|
return RTMP_MSG_UserControlMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsUserControlPacket::get_size()
|
||||||
|
{
|
||||||
|
if (event_type == SrcPCUCSetBufferLength) {
|
||||||
|
return 2 + 4 + 4;
|
||||||
|
} else {
|
||||||
|
return 2 + 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsUserControlPacket::encode_packet(SrsStream* stream)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (!stream->require(get_size())) {
|
||||||
ret = ERROR_RTMP_MESSAGE_ENCODE;
|
ret = ERROR_RTMP_MESSAGE_ENCODE;
|
||||||
srs_error("encode set bandwidth packet failed. ret=%d", ret);
|
srs_error("encode user control packet failed. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->write_2bytes(event_type);
|
stream->write_2bytes(event_type);
|
||||||
stream->write_4bytes(event_data);
|
stream->write_4bytes(event_data);
|
||||||
|
|
||||||
|
// when event type is set buffer length,
|
||||||
|
// read the extra buffer length.
|
||||||
|
if (event_type == SrcPCUCSetBufferLength) {
|
||||||
|
stream->write_2bytes(extra_data);
|
||||||
|
srs_verbose("user control message, buffer_length=%d", extra_data);
|
||||||
|
}
|
||||||
|
|
||||||
srs_verbose("encode PCUC packet success. "
|
srs_verbose("encode user control packet success. "
|
||||||
"event_type=%d, event_data=%d", event_type, event_data);
|
"event_type=%d, event_data=%d", event_type, event_data);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -129,6 +129,8 @@ private:
|
||||||
* when recv message, update the context.
|
* when recv message, update the context.
|
||||||
*/
|
*/
|
||||||
virtual int on_recv_message(SrsCommonMessage* msg);
|
virtual int on_recv_message(SrsCommonMessage* msg);
|
||||||
|
virtual int response_acknowledgement_message();
|
||||||
|
virtual int response_ping_message(int32_t timestamp);
|
||||||
/**
|
/**
|
||||||
* when message sentout, update the context.
|
* when message sentout, update the context.
|
||||||
*/
|
*/
|
||||||
|
@ -205,6 +207,7 @@ struct SrsMessageHeader
|
||||||
bool is_amf3_data();
|
bool is_amf3_data();
|
||||||
bool is_window_ackledgement_size();
|
bool is_window_ackledgement_size();
|
||||||
bool is_set_chunk_size();
|
bool is_set_chunk_size();
|
||||||
|
bool is_user_control_message();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -965,6 +968,7 @@ enum SrcPCUCEventType
|
||||||
* Stream Begin(=0) 4-bytes stream ID
|
* Stream Begin(=0) 4-bytes stream ID
|
||||||
* Stream EOF(=1) 4-bytes stream ID
|
* Stream EOF(=1) 4-bytes stream ID
|
||||||
* StreamDry(=2) 4-bytes stream ID
|
* StreamDry(=2) 4-bytes stream ID
|
||||||
|
* SetBufferLength(=3) 8-bytes 4bytes stream ID, 4bytes buffer length.
|
||||||
* StreamIsRecorded(=4) 4-bytes stream ID
|
* StreamIsRecorded(=4) 4-bytes stream ID
|
||||||
* PingRequest(=6) 4-bytes timestamp local server time
|
* PingRequest(=6) 4-bytes timestamp local server time
|
||||||
* PingResponse(=7) 4-bytes timestamp received ping request.
|
* PingResponse(=7) 4-bytes timestamp received ping request.
|
||||||
|
@ -975,21 +979,27 @@ enum SrcPCUCEventType
|
||||||
* +------------------------------+-------------------------
|
* +------------------------------+-------------------------
|
||||||
* Figure 5 Pay load for the ‘User Control Message’.
|
* Figure 5 Pay load for the ‘User Control Message’.
|
||||||
*/
|
*/
|
||||||
class SrsPCUC4BytesPacket : public SrsPacket
|
class SrsUserControlPacket : public SrsPacket
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef SrsPacket super;
|
typedef SrsPacket super;
|
||||||
protected:
|
protected:
|
||||||
virtual const char* get_class_name()
|
virtual const char* get_class_name()
|
||||||
{
|
{
|
||||||
return CLASS_NAME_STRING(SrsPCUC4BytesPacket);
|
return CLASS_NAME_STRING(SrsUserControlPacket);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
int16_t event_type;
|
int16_t event_type;
|
||||||
int32_t event_data;
|
int32_t event_data;
|
||||||
|
/**
|
||||||
|
* 4bytes if event_type is SetBufferLength; otherwise 0.
|
||||||
|
*/
|
||||||
|
int32_t extra_data;
|
||||||
public:
|
public:
|
||||||
SrsPCUC4BytesPacket();
|
SrsUserControlPacket();
|
||||||
virtual ~SrsPCUC4BytesPacket();
|
virtual ~SrsUserControlPacket();
|
||||||
|
public:
|
||||||
|
virtual int decode(SrsStream* stream);
|
||||||
public:
|
public:
|
||||||
virtual int get_perfer_cid();
|
virtual int get_perfer_cid();
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -412,7 +412,7 @@ int SrsRtmp::start_play(int stream_id)
|
||||||
// StreamBegin
|
// StreamBegin
|
||||||
if (true) {
|
if (true) {
|
||||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||||
SrsPCUC4BytesPacket* pkt = new SrsPCUC4BytesPacket();
|
SrsUserControlPacket* pkt = new SrsUserControlPacket();
|
||||||
|
|
||||||
pkt->event_type = SrcPCUCStreamBegin;
|
pkt->event_type = SrcPCUCStreamBegin;
|
||||||
pkt->event_data = stream_id;
|
pkt->event_data = stream_id;
|
||||||
|
|
Loading…
Reference in a new issue