mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
refine rtmp protocol stack, refer to go.rtmp
This commit is contained in:
parent
2e5337a26e
commit
ebf6203c3b
17 changed files with 1583 additions and 261 deletions
|
@ -382,6 +382,26 @@ int SrsRtmpClient::send_message(ISrsMessage* msg)
|
|||
return protocol->send_message(msg);
|
||||
}
|
||||
|
||||
int SrsRtmpClient::__recv_message(__SrsMessage** pmsg)
|
||||
{
|
||||
return protocol->__recv_message(pmsg);
|
||||
}
|
||||
|
||||
int SrsRtmpClient::__decode_message(__SrsMessage* msg, SrsPacket** ppacket)
|
||||
{
|
||||
return protocol->__decode_message(msg, ppacket);
|
||||
}
|
||||
|
||||
int SrsRtmpClient::__send_and_free_message(__SrsMessage* msg)
|
||||
{
|
||||
return protocol->__send_and_free_message(msg);
|
||||
}
|
||||
|
||||
int SrsRtmpClient::__send_and_free_packet(SrsPacket* packet, int stream_id)
|
||||
{
|
||||
return protocol->__send_and_free_packet(packet, stream_id);
|
||||
}
|
||||
|
||||
int SrsRtmpClient::handshake()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
@ -768,6 +788,26 @@ int SrsRtmpServer::send_message(ISrsMessage* msg)
|
|||
return protocol->send_message(msg);
|
||||
}
|
||||
|
||||
int SrsRtmpServer::__recv_message(__SrsMessage** pmsg)
|
||||
{
|
||||
return protocol->__recv_message(pmsg);
|
||||
}
|
||||
|
||||
int SrsRtmpServer::__decode_message(__SrsMessage* msg, SrsPacket** ppacket)
|
||||
{
|
||||
return protocol->__decode_message(msg, ppacket);
|
||||
}
|
||||
|
||||
int SrsRtmpServer::__send_and_free_message(__SrsMessage* msg)
|
||||
{
|
||||
return protocol->__send_and_free_message(msg);
|
||||
}
|
||||
|
||||
int SrsRtmpServer::__send_and_free_packet(SrsPacket* packet, int stream_id)
|
||||
{
|
||||
return protocol->__send_and_free_packet(packet, stream_id);
|
||||
}
|
||||
|
||||
int SrsRtmpServer::handshake()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
@ -794,13 +834,13 @@ int SrsRtmpServer::connect_app(SrsRequest* req)
|
|||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
SrsCommonMessage* msg = NULL;
|
||||
__SrsMessage* msg = NULL;
|
||||
SrsConnectAppPacket* pkt = NULL;
|
||||
if ((ret = srs_rtmp_expect_message<SrsConnectAppPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
|
||||
if ((ret = __srs_rtmp_expect_message<SrsConnectAppPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
|
||||
srs_error("expect connect app message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
SrsAutoFree(SrsCommonMessage, msg, false);
|
||||
SrsAutoFree(__SrsMessage, msg, false);
|
||||
srs_info("get connect app message");
|
||||
|
||||
SrsAmf0Any* prop = NULL;
|
||||
|
@ -833,13 +873,9 @@ int SrsRtmpServer::set_window_ack_size(int ack_size)
|
|||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();
|
||||
|
||||
pkt->ackowledgement_window_size = ack_size;
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send ack size message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -852,14 +888,10 @@ int SrsRtmpServer::set_peer_bandwidth(int bandwidth, int type)
|
|||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsSetPeerBandwidthPacket* pkt = new SrsSetPeerBandwidthPacket();
|
||||
|
||||
pkt->bandwidth = bandwidth;
|
||||
pkt->type = type;
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send set bandwidth message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -873,7 +905,6 @@ int SrsRtmpServer::response_connect_app(SrsRequest *req, const char* server_ip)
|
|||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket();
|
||||
|
||||
pkt->props->set("fmsVer", SrsAmf0Any::str("FMS/"RTMP_SIG_FMS_VER));
|
||||
|
@ -903,9 +934,7 @@ int SrsRtmpServer::response_connect_app(SrsRequest *req, const char* server_ip)
|
|||
data->set("srs_server_ip", SrsAmf0Any::str(server_ip));
|
||||
}
|
||||
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send connect app response message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -939,12 +968,8 @@ int SrsRtmpServer::on_bw_done()
|
|||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsOnBWDonePacket* pkt = new SrsOnBWDonePacket();
|
||||
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send onBWDone message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -959,13 +984,13 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string&
|
|||
int ret = ERROR_SUCCESS;
|
||||
|
||||
while (true) {
|
||||
SrsCommonMessage* msg = NULL;
|
||||
if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {
|
||||
__SrsMessage* msg = NULL;
|
||||
if ((ret = protocol->__recv_message(&msg)) != ERROR_SUCCESS) {
|
||||
srs_error("recv identify client message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SrsAutoFree(SrsCommonMessage, msg, false);
|
||||
SrsAutoFree(__SrsMessage, msg, false);
|
||||
|
||||
if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {
|
||||
srs_trace("identify ignore messages except "
|
||||
|
@ -973,12 +998,14 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string&
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) {
|
||||
SrsPacket* pkt = NULL;
|
||||
if ((ret = protocol->__decode_message(msg, &pkt)) != ERROR_SUCCESS) {
|
||||
srs_error("identify decode message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SrsPacket* pkt = msg->get_packet();
|
||||
SrsAutoFree(SrsPacket, pkt, false);
|
||||
|
||||
if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) {
|
||||
srs_info("identify client by create stream, play or flash publish.");
|
||||
return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name, duration);
|
||||
|
@ -1002,13 +1029,9 @@ int SrsRtmpServer::set_chunk_size(int chunk_size)
|
|||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket();
|
||||
|
||||
pkt->chunk_size = chunk_size;
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send set chunk size message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1023,14 +1046,10 @@ int SrsRtmpServer::start_play(int stream_id)
|
|||
|
||||
// StreamBegin
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsUserControlPacket* pkt = new SrsUserControlPacket();
|
||||
|
||||
pkt->event_type = SrcPCUCStreamBegin;
|
||||
pkt->event_data = stream_id;
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send PCUC(StreamBegin) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1039,7 +1058,6 @@ int SrsRtmpServer::start_play(int stream_id)
|
|||
|
||||
// onStatus(NetStream.Play.Reset)
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
|
||||
|
||||
pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelStatus));
|
||||
|
@ -1048,9 +1066,7 @@ int SrsRtmpServer::start_play(int stream_id)
|
|||
pkt->data->set(StatusDetails, SrsAmf0Any::str("stream"));
|
||||
pkt->data->set(StatusClientId, SrsAmf0Any::str(RTMP_SIG_CLIENT_ID));
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1059,7 +1075,6 @@ int SrsRtmpServer::start_play(int stream_id)
|
|||
|
||||
// onStatus(NetStream.Play.Start)
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
|
||||
|
||||
pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelStatus));
|
||||
|
@ -1068,9 +1083,7 @@ int SrsRtmpServer::start_play(int stream_id)
|
|||
pkt->data->set(StatusDetails, SrsAmf0Any::str("stream"));
|
||||
pkt->data->set(StatusClientId, SrsAmf0Any::str(RTMP_SIG_CLIENT_ID));
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1079,12 +1092,8 @@ int SrsRtmpServer::start_play(int stream_id)
|
|||
|
||||
// |RtmpSampleAccess(false, false)
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsSampleAccessPacket* pkt = new SrsSampleAccessPacket();
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send |RtmpSampleAccess(false, false) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1093,14 +1102,9 @@ int SrsRtmpServer::start_play(int stream_id)
|
|||
|
||||
// onStatus(NetStream.Data.Start)
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsOnStatusDataPacket* pkt = new SrsOnStatusDataPacket();
|
||||
|
||||
pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodeDataStart));
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send onStatus(NetStream.Data.Start) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1119,16 +1123,13 @@ int SrsRtmpServer::on_play_client_pause(int stream_id, bool is_pause)
|
|||
if (is_pause) {
|
||||
// onStatus(NetStream.Pause.Notify)
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
|
||||
|
||||
pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelStatus));
|
||||
pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodeStreamPause));
|
||||
pkt->data->set(StatusDescription, SrsAmf0Any::str("Paused stream."));
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send onStatus(NetStream.Pause.Notify) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1136,14 +1137,12 @@ int SrsRtmpServer::on_play_client_pause(int stream_id, bool is_pause)
|
|||
}
|
||||
// StreamEOF
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsUserControlPacket* pkt = new SrsUserControlPacket();
|
||||
|
||||
pkt->event_type = SrcPCUCStreamEOF;
|
||||
pkt->event_data = stream_id;
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send PCUC(StreamEOF) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1152,16 +1151,13 @@ int SrsRtmpServer::on_play_client_pause(int stream_id, bool is_pause)
|
|||
} else {
|
||||
// onStatus(NetStream.Unpause.Notify)
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
|
||||
|
||||
pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelStatus));
|
||||
pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodeStreamUnpause));
|
||||
pkt->data->set(StatusDescription, SrsAmf0Any::str("Unpaused stream."));
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send onStatus(NetStream.Unpause.Notify) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1169,14 +1165,12 @@ int SrsRtmpServer::on_play_client_pause(int stream_id, bool is_pause)
|
|||
}
|
||||
// StreanBegin
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsUserControlPacket* pkt = new SrsUserControlPacket();
|
||||
|
||||
pkt->event_type = SrcPCUCStreamBegin;
|
||||
pkt->event_data = stream_id;
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send PCUC(StreanBegin) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1194,25 +1188,21 @@ int SrsRtmpServer::start_fmle_publish(int stream_id)
|
|||
// FCPublish
|
||||
double fc_publish_tid = 0;
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = NULL;
|
||||
__SrsMessage* msg = NULL;
|
||||
SrsFMLEStartPacket* pkt = NULL;
|
||||
if ((ret = srs_rtmp_expect_message<SrsFMLEStartPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
|
||||
if ((ret = __srs_rtmp_expect_message<SrsFMLEStartPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
|
||||
srs_error("recv FCPublish message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("recv FCPublish request message success.");
|
||||
|
||||
SrsAutoFree(SrsCommonMessage, msg, false);
|
||||
SrsAutoFree(__SrsMessage, msg, false);
|
||||
fc_publish_tid = pkt->transaction_id;
|
||||
}
|
||||
// FCPublish response
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(fc_publish_tid);
|
||||
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send FCPublish response message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1222,25 +1212,21 @@ int SrsRtmpServer::start_fmle_publish(int stream_id)
|
|||
// createStream
|
||||
double create_stream_tid = 0;
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = NULL;
|
||||
__SrsMessage* msg = NULL;
|
||||
SrsCreateStreamPacket* pkt = NULL;
|
||||
if ((ret = srs_rtmp_expect_message<SrsCreateStreamPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
|
||||
if ((ret = __srs_rtmp_expect_message<SrsCreateStreamPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
|
||||
srs_error("recv createStream message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("recv createStream request message success.");
|
||||
|
||||
SrsAutoFree(SrsCommonMessage, msg, false);
|
||||
SrsAutoFree(__SrsMessage, msg, false);
|
||||
create_stream_tid = pkt->transaction_id;
|
||||
}
|
||||
// createStream response
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(create_stream_tid, stream_id);
|
||||
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send createStream response message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1249,28 +1235,25 @@ int SrsRtmpServer::start_fmle_publish(int stream_id)
|
|||
|
||||
// publish
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = NULL;
|
||||
__SrsMessage* msg = NULL;
|
||||
SrsPublishPacket* pkt = NULL;
|
||||
if ((ret = srs_rtmp_expect_message<SrsPublishPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
|
||||
if ((ret = __srs_rtmp_expect_message<SrsPublishPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
|
||||
srs_error("recv publish message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("recv publish request message success.");
|
||||
|
||||
SrsAutoFree(SrsCommonMessage, msg, false);
|
||||
SrsAutoFree(__SrsMessage, msg, false);
|
||||
}
|
||||
// publish response onFCPublish(NetStream.Publish.Start)
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
|
||||
|
||||
pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_PUBLISH;
|
||||
pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodePublishStart));
|
||||
pkt->data->set(StatusDescription, SrsAmf0Any::str("Started publishing stream."));
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send onFCPublish(NetStream.Publish.Start) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1278,7 +1261,6 @@ int SrsRtmpServer::start_fmle_publish(int stream_id)
|
|||
}
|
||||
// publish response onStatus(NetStream.Publish.Start)
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
|
||||
|
||||
pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelStatus));
|
||||
|
@ -1286,9 +1268,7 @@ int SrsRtmpServer::start_fmle_publish(int stream_id)
|
|||
pkt->data->set(StatusDescription, SrsAmf0Any::str("Started publishing stream."));
|
||||
pkt->data->set(StatusClientId, SrsAmf0Any::str(RTMP_SIG_CLIENT_ID));
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1306,16 +1286,13 @@ int SrsRtmpServer::fmle_unpublish(int stream_id, double unpublish_tid)
|
|||
|
||||
// publish response onFCUnpublish(NetStream.unpublish.Success)
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
|
||||
|
||||
pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH;
|
||||
pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodeUnpublishSuccess));
|
||||
pkt->data->set(StatusDescription, SrsAmf0Any::str("Stop publishing stream."));
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send onFCUnpublish(NetStream.unpublish.Success) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1323,12 +1300,8 @@ int SrsRtmpServer::fmle_unpublish(int stream_id, double unpublish_tid)
|
|||
}
|
||||
// FCUnpublish response
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(unpublish_tid);
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send FCUnpublish response message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1336,7 +1309,6 @@ int SrsRtmpServer::fmle_unpublish(int stream_id, double unpublish_tid)
|
|||
}
|
||||
// publish response onStatus(NetStream.Unpublish.Success)
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
|
||||
|
||||
pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelStatus));
|
||||
|
@ -1344,9 +1316,7 @@ int SrsRtmpServer::fmle_unpublish(int stream_id, double unpublish_tid)
|
|||
pkt->data->set(StatusDescription, SrsAmf0Any::str("Stream is now unpublished"));
|
||||
pkt->data->set(StatusClientId, SrsAmf0Any::str(RTMP_SIG_CLIENT_ID));
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send onStatus(NetStream.Unpublish.Success) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1364,7 +1334,6 @@ int SrsRtmpServer::start_flash_publish(int stream_id)
|
|||
|
||||
// publish response onStatus(NetStream.Publish.Start)
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
|
||||
|
||||
pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelStatus));
|
||||
|
@ -1372,9 +1341,7 @@ int SrsRtmpServer::start_flash_publish(int stream_id)
|
|||
pkt->data->set(StatusDescription, SrsAmf0Any::str("Started publishing stream."));
|
||||
pkt->data->set(StatusClientId, SrsAmf0Any::str(RTMP_SIG_CLIENT_ID));
|
||||
|
||||
msg->set_packet(pkt, stream_id);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
|
||||
srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1391,12 +1358,8 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int
|
|||
int ret = ERROR_SUCCESS;
|
||||
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id);
|
||||
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send createStream response message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1404,13 +1367,13 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int
|
|||
}
|
||||
|
||||
while (true) {
|
||||
SrsCommonMessage* msg = NULL;
|
||||
if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {
|
||||
__SrsMessage* msg = NULL;
|
||||
if ((ret = protocol->__recv_message(&msg)) != ERROR_SUCCESS) {
|
||||
srs_error("recv identify client message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SrsAutoFree(SrsCommonMessage, msg, false);
|
||||
SrsAutoFree(__SrsMessage, msg, false);
|
||||
|
||||
if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {
|
||||
srs_trace("identify ignore messages except "
|
||||
|
@ -1418,12 +1381,14 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) {
|
||||
SrsPacket* pkt = NULL;
|
||||
if ((ret = protocol->__decode_message(msg, &pkt)) != ERROR_SUCCESS) {
|
||||
srs_error("identify decode message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SrsAutoFree(SrsPacket, pkt, false);
|
||||
|
||||
SrsPacket* pkt = msg->get_packet();
|
||||
if (dynamic_cast<SrsPlayPacket*>(pkt)) {
|
||||
srs_info("level1 identify client by play.");
|
||||
return identify_play_client(dynamic_cast<SrsPlayPacket*>(pkt), type, stream_name, duration);
|
||||
|
@ -1448,12 +1413,8 @@ int SrsRtmpServer::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmp
|
|||
|
||||
// releaseStream response
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id);
|
||||
|
||||
msg->set_packet(pkt, 0);
|
||||
|
||||
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = protocol->__send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send releaseStream response message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ class SrsPublishPacket;
|
|||
class SrsSharedPtrMessage;
|
||||
class SrsOnMetaDataPacket;
|
||||
class SrsPlayPacket;
|
||||
class __SrsMessage;
|
||||
class SrsPacket;
|
||||
|
||||
/**
|
||||
* the original request from client.
|
||||
|
@ -164,6 +166,10 @@ public:
|
|||
virtual int get_send_kbps();
|
||||
virtual int recv_message(SrsCommonMessage** pmsg);
|
||||
virtual int send_message(ISrsMessage* msg);
|
||||
virtual int __recv_message(__SrsMessage** pmsg);
|
||||
virtual int __decode_message(__SrsMessage* msg, SrsPacket** ppacket);
|
||||
virtual int __send_and_free_message(__SrsMessage* msg);
|
||||
virtual int __send_and_free_packet(SrsPacket* packet, int stream_id);
|
||||
public:
|
||||
// try complex, then simple handshake.
|
||||
virtual int handshake();
|
||||
|
@ -209,6 +215,10 @@ public:
|
|||
virtual int get_send_kbps();
|
||||
virtual int recv_message(SrsCommonMessage** pmsg);
|
||||
virtual int send_message(ISrsMessage* msg);
|
||||
virtual int __recv_message(__SrsMessage** pmsg);
|
||||
virtual int __decode_message(__SrsMessage* msg, SrsPacket** ppacket);
|
||||
virtual int __send_and_free_message(__SrsMessage* msg);
|
||||
virtual int __send_and_free_packet(SrsPacket* packet, int stream_id);
|
||||
public:
|
||||
virtual int handshake();
|
||||
virtual int connect_app(SrsRequest* req);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -45,6 +45,9 @@ class SrsChunkStream;
|
|||
class SrsAmf0Object;
|
||||
class SrsAmf0Any;
|
||||
class ISrsMessage;
|
||||
class SrsMessageHeader;
|
||||
class __SrsMessage;
|
||||
class __SrsChunkStream;
|
||||
|
||||
// the following is the timeout for rtmp protocol,
|
||||
// to avoid death connection.
|
||||
|
@ -110,6 +113,9 @@ private:
|
|||
// peer in
|
||||
private:
|
||||
std::map<int, SrsChunkStream*> chunk_streams;
|
||||
// TODO: FIXME: rename to chunk_streams
|
||||
std::map<int, __SrsChunkStream*> __chunk_streams;
|
||||
SrsStream* decode_stream;
|
||||
SrsBuffer* buffer;
|
||||
int32_t in_chunk_size;
|
||||
AckWindowSize in_ack_size;
|
||||
|
@ -125,6 +131,7 @@ public:
|
|||
SrsProtocol(ISrsProtocolReaderWriter* io);
|
||||
virtual ~SrsProtocol();
|
||||
public:
|
||||
// TODO: FIXME: to private.
|
||||
std::string get_request_name(double transcationId);
|
||||
/**
|
||||
* set the timeout in us.
|
||||
|
@ -138,6 +145,82 @@ public:
|
|||
virtual int64_t get_send_bytes();
|
||||
virtual int get_recv_kbps();
|
||||
virtual int get_send_kbps();
|
||||
public:
|
||||
/**
|
||||
* recv a RTMP message, which is bytes oriented.
|
||||
* user can use decode_message to get the decoded RTMP packet.
|
||||
* @param pmsg, set the received message,
|
||||
* always NULL if error,
|
||||
* NULL for unknown packet but return success.
|
||||
* never NULL if decode success.
|
||||
*/
|
||||
virtual int __recv_message(__SrsMessage** pmsg);
|
||||
/**
|
||||
* decode bytes oriented RTMP message to RTMP packet,
|
||||
* @param ppacket, output decoded packet,
|
||||
* always NULL if error, never NULL if success.
|
||||
* @return error when unknown packet, error when decode failed.
|
||||
*/
|
||||
virtual int __decode_message(__SrsMessage* msg, SrsPacket** ppacket);
|
||||
/**
|
||||
* send the RTMP message and always free it.
|
||||
* user must never free or use the msg after this method,
|
||||
* for it will always free the msg.
|
||||
* @param msg, the msg to send out, never be NULL.
|
||||
*/
|
||||
virtual int __send_and_free_message(__SrsMessage* msg);
|
||||
/**
|
||||
* send the RTMP packet and always free it.
|
||||
* user must never free or use the packet after this method,
|
||||
* for it will always free the packet.
|
||||
* @param packet, the packet to send out, never be NULL.
|
||||
* @param stream_id, the stream id of packet to send over, 0 for control message.
|
||||
*/
|
||||
virtual int __send_and_free_packet(SrsPacket* packet, int stream_id);
|
||||
private:
|
||||
/**
|
||||
* imp for __send_and_free_message
|
||||
* @param packet the packet of message, NULL for raw message.
|
||||
*/
|
||||
virtual int __do_send_and_free_message(__SrsMessage* msg, SrsPacket* packet);
|
||||
/**
|
||||
* imp for __decode_message
|
||||
*/
|
||||
virtual int __do_decode_message(SrsMessageHeader& header, SrsStream* stream, SrsPacket** ppacket);
|
||||
/**
|
||||
* recv bytes oriented RTMP message from protocol stack.
|
||||
* return error if error occur and nerver set the pmsg,
|
||||
* return success and pmsg set to NULL if no entire message got,
|
||||
* return success and pmsg set to entire message if got one.
|
||||
*/
|
||||
virtual int __recv_interlaced_message(__SrsMessage** pmsg);
|
||||
/**
|
||||
* read the chunk basic header(fmt, cid) from chunk stream.
|
||||
* user can discovery a SrsChunkStream by cid.
|
||||
* @bh_size return the chunk basic header size, to remove the used bytes when finished.
|
||||
*/
|
||||
virtual int __read_basic_header(char& fmt, int& cid, int& bh_size);
|
||||
/**
|
||||
* read the chunk message header(timestamp, payload_length, message_type, stream_id)
|
||||
* from chunk stream and save to SrsChunkStream.
|
||||
* @mh_size return the chunk message header size, to remove the used bytes when finished.
|
||||
*/
|
||||
virtual int __read_message_header(__SrsChunkStream* chunk, char fmt, int bh_size, int& mh_size);
|
||||
/**
|
||||
* read the chunk payload, remove the used bytes in buffer,
|
||||
* if got entire message, set the pmsg.
|
||||
* @payload_size read size in this roundtrip, generally a chunk size or left message size.
|
||||
*/
|
||||
virtual int __read_message_payload(__SrsChunkStream* chunk, int bh_size, int mh_size, int& payload_size, __SrsMessage** pmsg);
|
||||
/**
|
||||
* when recv message, update the context.
|
||||
*/
|
||||
virtual int __on_recv_message(__SrsMessage* msg);
|
||||
/**
|
||||
* when message sentout, update the context.
|
||||
*/
|
||||
virtual int __on_send_message(__SrsMessage* msg, SrsPacket* packet);
|
||||
public:
|
||||
/**
|
||||
* recv a message with raw/undecoded payload from peer.
|
||||
* the payload is not decoded, use srs_rtmp_expect_message<T> if requires
|
||||
|
@ -226,6 +309,16 @@ struct SrsMessageHeader
|
|||
*/
|
||||
int64_t timestamp;
|
||||
|
||||
public:
|
||||
/**
|
||||
* get the perfered cid(chunk stream id) which sendout over.
|
||||
* set at decoding, and canbe used for directly send message,
|
||||
* for example, dispatch to all connections.
|
||||
* @see: SrsSharedPtrMessage.SrsSharedPtr.perfer_cid
|
||||
*/
|
||||
int perfer_cid;
|
||||
|
||||
public:
|
||||
SrsMessageHeader();
|
||||
virtual ~SrsMessageHeader();
|
||||
|
||||
|
@ -283,6 +376,109 @@ public:
|
|||
virtual ~SrsChunkStream();
|
||||
};
|
||||
|
||||
/**
|
||||
* incoming chunk stream maybe interlaced,
|
||||
* use the chunk stream to cache the input RTMP chunk streams.
|
||||
*/
|
||||
class __SrsChunkStream
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* represents the basic header fmt,
|
||||
* which used to identify the variant message header type.
|
||||
*/
|
||||
char fmt;
|
||||
/**
|
||||
* represents the basic header cid,
|
||||
* which is the chunk stream id.
|
||||
*/
|
||||
int cid;
|
||||
/**
|
||||
* cached message header
|
||||
*/
|
||||
SrsMessageHeader header;
|
||||
/**
|
||||
* whether the chunk message header has extended timestamp.
|
||||
*/
|
||||
bool extended_timestamp;
|
||||
/**
|
||||
* partially read message.
|
||||
*/
|
||||
__SrsMessage* msg;
|
||||
/**
|
||||
* decoded msg count, to identify whether the chunk stream is fresh.
|
||||
*/
|
||||
int64_t msg_count;
|
||||
public:
|
||||
__SrsChunkStream(int _cid);
|
||||
virtual ~__SrsChunkStream();
|
||||
};
|
||||
|
||||
/**
|
||||
* message is raw data RTMP message, bytes oriented,
|
||||
* protcol always recv RTMP message, and can send RTMP message or RTMP packet.
|
||||
* the shared-ptr message is a special RTMP message, use ref-count for performance issue.
|
||||
*/
|
||||
class __SrsMessage
|
||||
{
|
||||
// 4.1. Message Header
|
||||
public:
|
||||
SrsMessageHeader header;
|
||||
// 4.2. Message Payload
|
||||
public:
|
||||
/**
|
||||
* The other part which is the payload is the actual data that is
|
||||
* contained in the message. For example, it could be some audio samples
|
||||
* or compressed video data. The payload format and interpretation are
|
||||
* beyond the scope of this document.
|
||||
*/
|
||||
int32_t size;
|
||||
int8_t* payload;
|
||||
public:
|
||||
__SrsMessage();
|
||||
virtual ~__SrsMessage();
|
||||
};
|
||||
|
||||
/**
|
||||
* shared ptr message.
|
||||
* for audio/video/data message that need less memory copy.
|
||||
* and only for output.
|
||||
*/
|
||||
class __SrsSharedPtrMessage : public __SrsMessage
|
||||
{
|
||||
private:
|
||||
struct __SrsSharedPtr
|
||||
{
|
||||
char* payload;
|
||||
int size;
|
||||
int shared_count;
|
||||
|
||||
__SrsSharedPtr();
|
||||
virtual ~__SrsSharedPtr();
|
||||
};
|
||||
__SrsSharedPtr* ptr;
|
||||
public:
|
||||
__SrsSharedPtrMessage();
|
||||
virtual ~__SrsSharedPtrMessage();
|
||||
public:
|
||||
/**
|
||||
* set the shared payload.
|
||||
* we will detach the payload of source,
|
||||
* so ensure donot use it before.
|
||||
*/
|
||||
virtual int initialize(__SrsMessage* source);
|
||||
/**
|
||||
* set the shared payload.
|
||||
* use source header, and specified param payload.
|
||||
*/
|
||||
virtual int initialize(SrsMessageHeader* source, char* payload, int size);
|
||||
public:
|
||||
/**
|
||||
* copy current shared ptr message, use ref-count.
|
||||
*/
|
||||
virtual __SrsSharedPtrMessage* copy();
|
||||
};
|
||||
|
||||
/**
|
||||
* message to output.
|
||||
*/
|
||||
|
@ -1215,5 +1411,44 @@ int srs_rtmp_expect_message(SrsProtocol* protocol, SrsCommonMessage** pmsg, T**
|
|||
|
||||
return ret;
|
||||
}
|
||||
template<class T>
|
||||
int __srs_rtmp_expect_message(SrsProtocol* protocol, __SrsMessage** pmsg, T** ppacket)
|
||||
{
|
||||
*pmsg = NULL;
|
||||
*ppacket = NULL;
|
||||
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
while (true) {
|
||||
__SrsMessage* msg = NULL;
|
||||
if ((ret = protocol->__recv_message(&msg)) != ERROR_SUCCESS) {
|
||||
srs_error("recv message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_verbose("recv message success.");
|
||||
|
||||
SrsPacket* packet = NULL;
|
||||
if ((ret = protocol->__decode_message(msg, &packet)) != ERROR_SUCCESS) {
|
||||
srs_error("decode message failed. ret=%d", ret);
|
||||
srs_freep(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
T* pkt = dynamic_cast<T*>(packet);
|
||||
if (!pkt) {
|
||||
srs_trace("drop message(type=%d, size=%d, time=%"PRId64", sid=%d).",
|
||||
msg->header.message_type, msg->header.payload_length,
|
||||
msg->header.timestamp, msg->header.stream_id);
|
||||
srs_freep(msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
*pmsg = msg;
|
||||
*ppacket = pkt;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue