winlin

support FMLE publish streaming

@@ -28,15 +28,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -28,15 +28,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include <srs_core_error.hpp> 28 #include <srs_core_error.hpp>
29 #include <srs_core_log.hpp> 29 #include <srs_core_log.hpp>
30 #include <srs_core_rtmp.hpp> 30 #include <srs_core_rtmp.hpp>
31 -  
32 -// default stream id for response the createStream request.  
33 -#define SRS_DEFAULT_SID 1 31 +#include <srs_core_protocol.hpp>
  32 +#include <srs_core_auto_free.hpp>
34 33
35 SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) 34 SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd)
36 : SrsConnection(srs_server, client_stfd) 35 : SrsConnection(srs_server, client_stfd)
37 { 36 {
38 ip = NULL; 37 ip = NULL;
39 req = new SrsRequest(); 38 req = new SrsRequest();
  39 + res = new SrsResponse();
40 rtmp = new SrsRtmp(client_stfd); 40 rtmp = new SrsRtmp(client_stfd);
41 } 41 }
42 42
@@ -44,6 +44,7 @@ SrsClient::~SrsClient() @@ -44,6 +44,7 @@ SrsClient::~SrsClient()
44 { 44 {
45 srs_freepa(ip); 45 srs_freepa(ip);
46 srs_freep(req); 46 srs_freep(req);
  47 + srs_freep(res);
47 srs_freep(rtmp); 48 srs_freep(rtmp);
48 } 49 }
49 50
@@ -97,9 +98,8 @@ int SrsClient::do_cycle() @@ -97,9 +98,8 @@ int SrsClient::do_cycle()
97 } 98 }
98 srs_verbose("on_bw_done success"); 99 srs_verbose("on_bw_done success");
99 100
100 - int stream_id = SRS_DEFAULT_SID;  
101 SrsClientType type; 101 SrsClientType type;
102 - if ((ret = rtmp->identify_client(stream_id, type, req->stream)) != ERROR_SUCCESS) { 102 + if ((ret = rtmp->identify_client(res->stream_id, type, req->stream)) != ERROR_SUCCESS) {
103 srs_error("identify client failed. ret=%d", ret); 103 srs_error("identify client failed. ret=%d", ret);
104 return ret; 104 return ret;
105 } 105 }
@@ -117,13 +117,23 @@ int SrsClient::do_cycle() @@ -117,13 +117,23 @@ int SrsClient::do_cycle()
117 case SrsClientPlay: { 117 case SrsClientPlay: {
118 srs_verbose("start to play stream %s.", req->stream.c_str()); 118 srs_verbose("start to play stream %s.", req->stream.c_str());
119 119
120 - if ((ret = rtmp->start_play(stream_id)) != ERROR_SUCCESS) { 120 + if ((ret = rtmp->start_play(res->stream_id)) != ERROR_SUCCESS) {
121 srs_error("start to play stream failed. ret=%d", ret); 121 srs_error("start to play stream failed. ret=%d", ret);
122 return ret; 122 return ret;
123 } 123 }
124 srs_info("start to play stream %s success", req->stream.c_str()); 124 srs_info("start to play stream %s success", req->stream.c_str());
125 return streaming_play(); 125 return streaming_play();
126 } 126 }
  127 + case SrsClientPublish: {
  128 + srs_verbose("start to publish stream %s.", req->stream.c_str());
  129 +
  130 + if ((ret = rtmp->start_publish(res->stream_id)) != ERROR_SUCCESS) {
  131 + srs_error("start to publish stream failed. ret=%d", ret);
  132 + return ret;
  133 + }
  134 + srs_info("start to publish stream %s success", req->stream.c_str());
  135 + return streaming_publish();
  136 + }
127 default: { 137 default: {
128 ret = ERROR_SYSTEM_CLIENT_INVALID; 138 ret = ERROR_SYSTEM_CLIENT_INVALID;
129 srs_info("invalid client type=%d. ret=%d", type, ret); 139 srs_info("invalid client type=%d. ret=%d", type, ret);
@@ -140,6 +150,39 @@ int SrsClient::streaming_play() @@ -140,6 +150,39 @@ int SrsClient::streaming_play()
140 return ret; 150 return ret;
141 } 151 }
142 152
  153 +int SrsClient::streaming_publish()
  154 +{
  155 + int ret = ERROR_SUCCESS;
  156 +
  157 + while (true) {
  158 + SrsMessage* msg = NULL;
  159 + if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) {
  160 + srs_error("recv identify client message failed. ret=%d", ret);
  161 + return ret;
  162 + }
  163 +
  164 + SrsAutoFree(SrsMessage, msg, false);
  165 +
  166 + // process UnPublish event.
  167 + if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) {
  168 + if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {
  169 + srs_error("decode unpublish message failed. ret=%d", ret);
  170 + return ret;
  171 + }
  172 +
  173 + SrsPacket* pkt = msg->get_packet();
  174 + if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
  175 + SrsFMLEStartPacket* unpublish = dynamic_cast<SrsFMLEStartPacket*>(pkt);
  176 + return rtmp->fmle_unpublish(res->stream_id, unpublish->transaction_id);
  177 + }
  178 +
  179 + srs_trace("ignore AMF0/AMF3 command message.");
  180 + }
  181 + }
  182 +
  183 + return ret;
  184 +}
  185 +
143 int SrsClient::get_peer_ip() 186 int SrsClient::get_peer_ip()
144 { 187 {
145 int ret = ERROR_SUCCESS; 188 int ret = ERROR_SUCCESS;
@@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 34
35 class SrsRtmp; 35 class SrsRtmp;
36 class SrsRequest; 36 class SrsRequest;
  37 +class SrsResponse;
37 38
38 /** 39 /**
39 * the client provides the main logic control for RTMP clients. 40 * the client provides the main logic control for RTMP clients.
@@ -43,6 +44,7 @@ class SrsClient : public SrsConnection @@ -43,6 +44,7 @@ class SrsClient : public SrsConnection
43 private: 44 private:
44 char* ip; 45 char* ip;
45 SrsRequest* req; 46 SrsRequest* req;
  47 + SrsResponse* res;
46 SrsRtmp* rtmp; 48 SrsRtmp* rtmp;
47 public: 49 public:
48 SrsClient(SrsServer* srs_server, st_netfd_t client_stfd); 50 SrsClient(SrsServer* srs_server, st_netfd_t client_stfd);
@@ -51,6 +53,7 @@ protected: @@ -51,6 +53,7 @@ protected:
51 virtual int do_cycle(); 53 virtual int do_cycle();
52 private: 54 private:
53 virtual int streaming_play(); 55 virtual int streaming_play();
  56 + virtual int streaming_publish();
54 virtual int get_peer_ip(); 57 virtual int get_peer_ip();
55 }; 58 };
56 59
@@ -199,6 +199,7 @@ messages. @@ -199,6 +199,7 @@ messages.
199 #define RTMP_AMF0_COMMAND_RESULT "_result" 199 #define RTMP_AMF0_COMMAND_RESULT "_result"
200 #define RTMP_AMF0_COMMAND_RELEASE_STREAM "releaseStream" 200 #define RTMP_AMF0_COMMAND_RELEASE_STREAM "releaseStream"
201 #define RTMP_AMF0_COMMAND_FC_PUBLISH "FCPublish" 201 #define RTMP_AMF0_COMMAND_FC_PUBLISH "FCPublish"
  202 +#define RTMP_AMF0_COMMAND_UNPUBLISH "FCUnpublish"
202 #define RTMP_AMF0_COMMAND_PUBLISH "publish" 203 #define RTMP_AMF0_COMMAND_PUBLISH "publish"
203 #define RTMP_AMF0_DATA_SAMPLE_ACCESS "|RtmpSampleAccess" 204 #define RTMP_AMF0_DATA_SAMPLE_ACCESS "|RtmpSampleAccess"
204 205
@@ -979,6 +980,10 @@ int SrsMessage::decode_packet() @@ -979,6 +980,10 @@ int SrsMessage::decode_packet()
979 srs_info("decode the AMF0/AMF3 command(publish message)."); 980 srs_info("decode the AMF0/AMF3 command(publish message).");
980 packet = new SrsPublishPacket(); 981 packet = new SrsPublishPacket();
981 return packet->decode(stream); 982 return packet->decode(stream);
  983 + } else if(command == RTMP_AMF0_COMMAND_UNPUBLISH) {
  984 + srs_info("decode the AMF0/AMF3 command(unpublish message).");
  985 + packet = new SrsFMLEStartPacket();
  986 + return packet->decode(stream);
982 } 987 }
983 988
984 // default packet to drop message. 989 // default packet to drop message.
@@ -1383,7 +1388,8 @@ int SrsFMLEStartPacket::decode(SrsStream* stream) @@ -1383,7 +1388,8 @@ int SrsFMLEStartPacket::decode(SrsStream* stream)
1383 } 1388 }
1384 if (command_name.empty() 1389 if (command_name.empty()
1385 || (command_name != RTMP_AMF0_COMMAND_RELEASE_STREAM 1390 || (command_name != RTMP_AMF0_COMMAND_RELEASE_STREAM
1386 - && command_name != RTMP_AMF0_COMMAND_FC_PUBLISH) 1391 + && command_name != RTMP_AMF0_COMMAND_FC_PUBLISH
  1392 + && command_name != RTMP_AMF0_COMMAND_UNPUBLISH)
1387 ) { 1393 ) {
1388 ret = ERROR_RTMP_AMF0_DECODE; 1394 ret = ERROR_RTMP_AMF0_DECODE;
1389 srs_error("amf0 decode FMLE start command_name failed. " 1395 srs_error("amf0 decode FMLE start command_name failed. "
@@ -53,9 +53,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -53,9 +53,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
53 #define StatusCodeStreamStart "NetStream.Play.Start" 53 #define StatusCodeStreamStart "NetStream.Play.Start"
54 #define StatusCodePublishStart "NetStream.Publish.Start" 54 #define StatusCodePublishStart "NetStream.Publish.Start"
55 #define StatusCodeDataStart "NetStream.Data.Start" 55 #define StatusCodeDataStart "NetStream.Data.Start"
  56 +#define StatusCodeUnpublishSuccess "NetStream.Unpublish.Success"
56 57
57 // FMLE 58 // FMLE
58 #define RTMP_AMF0_COMMAND_ON_FC_PUBLISH "onFCPublish" 59 #define RTMP_AMF0_COMMAND_ON_FC_PUBLISH "onFCPublish"
  60 +#define RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH "onFCUnpublish"
  61 +
  62 +// default stream id for response the createStream request.
  63 +#define SRS_DEFAULT_SID 1
59 64
60 SrsRequest::SrsRequest() 65 SrsRequest::SrsRequest()
61 { 66 {
@@ -107,6 +112,15 @@ int SrsRequest::discovery_app() @@ -107,6 +112,15 @@ int SrsRequest::discovery_app()
107 return ret; 112 return ret;
108 } 113 }
109 114
  115 +SrsResponse::SrsResponse()
  116 +{
  117 + stream_id = SRS_DEFAULT_SID;
  118 +}
  119 +
  120 +SrsResponse::~SrsResponse()
  121 +{
  122 +}
  123 +
110 SrsRtmp::SrsRtmp(st_netfd_t client_stfd) 124 SrsRtmp::SrsRtmp(st_netfd_t client_stfd)
111 { 125 {
112 protocol = new SrsProtocol(client_stfd); 126 protocol = new SrsProtocol(client_stfd);
@@ -164,6 +178,11 @@ int SrsRtmp::handshake() @@ -164,6 +178,11 @@ int SrsRtmp::handshake()
164 return ret; 178 return ret;
165 } 179 }
166 180
  181 +int SrsRtmp::recv_message(SrsMessage** pmsg)
  182 +{
  183 + return protocol->recv_message(pmsg);
  184 +}
  185 +
167 int SrsRtmp::connect_app(SrsRequest* req) 186 int SrsRtmp::connect_app(SrsRequest* req)
168 { 187 {
169 int ret = ERROR_SUCCESS; 188 int ret = ERROR_SUCCESS;
@@ -329,7 +348,7 @@ int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& st @@ -329,7 +348,7 @@ int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& st
329 if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) { 348 if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
330 srs_info("identify client by releaseStream, fmle publish."); 349 srs_info("identify client by releaseStream, fmle publish.");
331 return identify_fmle_publish_client( 350 return identify_fmle_publish_client(
332 - dynamic_cast<SrsFMLEStartPacket*>(pkt), stream_id, type, stream_name); 351 + dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name);
333 } 352 }
334 353
335 srs_trace("ignore AMF0/AMF3 command message."); 354 srs_trace("ignore AMF0/AMF3 command message.");
@@ -452,79 +471,10 @@ int SrsRtmp::start_play(int stream_id) @@ -452,79 +471,10 @@ int SrsRtmp::start_play(int stream_id)
452 return ret; 471 return ret;
453 } 472 }
454 473
455 -int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name)  
456 -{  
457 - int ret = ERROR_SUCCESS;  
458 -  
459 - if (true) {  
460 - SrsMessage* msg = new SrsMessage();  
461 - SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id);  
462 -  
463 - msg->set_packet(pkt, 0);  
464 -  
465 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
466 - srs_error("send createStream response message failed. ret=%d", ret);  
467 - return ret;  
468 - }  
469 - srs_info("send createStream response message success.");  
470 - }  
471 -  
472 - while (true) {  
473 - SrsMessage* msg = NULL;  
474 - if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {  
475 - srs_error("recv identify client message failed. ret=%d", ret);  
476 - return ret;  
477 - }  
478 -  
479 - SrsAutoFree(SrsMessage, msg, false);  
480 -  
481 - if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {  
482 - srs_trace("identify ignore messages except "  
483 - "AMF0/AMF3 command message. type=%#x", msg->header.message_type);  
484 - continue;  
485 - }  
486 -  
487 - if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {  
488 - srs_error("identify decode message failed. ret=%d", ret);  
489 - return ret;  
490 - }  
491 -  
492 - SrsPacket* pkt = msg->get_packet();  
493 - if (dynamic_cast<SrsPlayPacket*>(pkt)) {  
494 - SrsPlayPacket* play = dynamic_cast<SrsPlayPacket*>(pkt);  
495 - type = SrsClientPlay;  
496 - stream_name = play->stream_name;  
497 - srs_trace("identity client type=play, stream_name=%s", stream_name.c_str());  
498 - return ret;  
499 - }  
500 -  
501 - srs_trace("ignore AMF0/AMF3 command message.");  
502 - }  
503 -  
504 - return ret;  
505 -}  
506 -  
507 -int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id, SrsClientType& type, std::string& stream_name) 474 +int SrsRtmp::start_publish(int stream_id)
508 { 475 {
509 int ret = ERROR_SUCCESS; 476 int ret = ERROR_SUCCESS;
510 477
511 - type = SrsClientPublish;  
512 - stream_name = req->stream_name;  
513 -  
514 - // createStream response  
515 - if (true) {  
516 - SrsMessage* msg = new SrsMessage();  
517 - SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id);  
518 -  
519 - msg->set_packet(pkt, 0);  
520 -  
521 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
522 - srs_error("send releaseStream response message failed. ret=%d", ret);  
523 - return ret;  
524 - }  
525 - srs_info("send releaseStream response message success.");  
526 - }  
527 -  
528 // FCPublish 478 // FCPublish
529 double fc_publish_tid = 0; 479 double fc_publish_tid = 0;
530 if (true) { 480 if (true) {
@@ -629,6 +579,84 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id @@ -629,6 +579,84 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id
629 srs_info("send onStatus(NetStream.Publish.Start) message success."); 579 srs_info("send onStatus(NetStream.Publish.Start) message success.");
630 } 580 }
631 581
  582 + return ret;
  583 +}
  584 +
  585 +int SrsRtmp::fmle_unpublish(int stream_id, double unpublish_tid)
  586 +{
  587 + int ret = ERROR_SUCCESS;
  588 +
  589 + // publish response onFCUnpublish(NetStream.unpublish.Success)
  590 + if (true) {
  591 + SrsMessage* msg = new SrsMessage();
  592 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  593 +
  594 + pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH;
  595 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess));
  596 + pkt->data->set(StatusDescription, new SrsAmf0String("Stop publishing stream."));
  597 +
  598 + msg->set_packet(pkt, stream_id);
  599 +
  600 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  601 + srs_error("send onFCUnpublish(NetStream.unpublish.Success) message failed. ret=%d", ret);
  602 + return ret;
  603 + }
  604 + srs_info("send onFCUnpublish(NetStream.unpublish.Success) message success.");
  605 + }
  606 + // FCUnpublish response
  607 + if (true) {
  608 + SrsMessage* msg = new SrsMessage();
  609 + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(unpublish_tid);
  610 +
  611 + msg->set_packet(pkt, stream_id);
  612 +
  613 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  614 + srs_error("send FCUnpublish response message failed. ret=%d", ret);
  615 + return ret;
  616 + }
  617 + srs_info("send FCUnpublish response message success.");
  618 + }
  619 + // publish response onStatus(NetStream.Unpublish.Success)
  620 + if (true) {
  621 + SrsMessage* msg = new SrsMessage();
  622 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  623 +
  624 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  625 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess));
  626 + pkt->data->set(StatusDescription, new SrsAmf0String("Stream is now unpublished"));
  627 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  628 +
  629 + msg->set_packet(pkt, stream_id);
  630 +
  631 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  632 + srs_error("send onStatus(NetStream.Unpublish.Success) message failed. ret=%d", ret);
  633 + return ret;
  634 + }
  635 + srs_info("send onStatus(NetStream.Unpublish.Success) message success.");
  636 + }
  637 +
  638 + srs_info("FMLE unpublish success.");
  639 +
  640 + return ret;
  641 +}
  642 +
  643 +int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name)
  644 +{
  645 + int ret = ERROR_SUCCESS;
  646 +
  647 + if (true) {
  648 + SrsMessage* msg = new SrsMessage();
  649 + SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id);
  650 +
  651 + msg->set_packet(pkt, 0);
  652 +
  653 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  654 + srs_error("send createStream response message failed. ret=%d", ret);
  655 + return ret;
  656 + }
  657 + srs_info("send createStream response message success.");
  658 + }
  659 +
632 while (true) { 660 while (true) {
633 SrsMessage* msg = NULL; 661 SrsMessage* msg = NULL;
634 if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) { 662 if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {
@@ -637,6 +665,52 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id @@ -637,6 +665,52 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id
637 } 665 }
638 666
639 SrsAutoFree(SrsMessage, msg, false); 667 SrsAutoFree(SrsMessage, msg, false);
  668 +
  669 + if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {
  670 + srs_trace("identify ignore messages except "
  671 + "AMF0/AMF3 command message. type=%#x", msg->header.message_type);
  672 + continue;
  673 + }
  674 +
  675 + if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {
  676 + srs_error("identify decode message failed. ret=%d", ret);
  677 + return ret;
  678 + }
  679 +
  680 + SrsPacket* pkt = msg->get_packet();
  681 + if (dynamic_cast<SrsPlayPacket*>(pkt)) {
  682 + SrsPlayPacket* play = dynamic_cast<SrsPlayPacket*>(pkt);
  683 + type = SrsClientPlay;
  684 + stream_name = play->stream_name;
  685 + srs_trace("identity client type=play, stream_name=%s", stream_name.c_str());
  686 + return ret;
  687 + }
  688 +
  689 + srs_trace("ignore AMF0/AMF3 command message.");
  690 + }
  691 +
  692 + return ret;
  693 +}
  694 +
  695 +int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, std::string& stream_name)
  696 +{
  697 + int ret = ERROR_SUCCESS;
  698 +
  699 + type = SrsClientPublish;
  700 + stream_name = req->stream_name;
  701 +
  702 + // releaseStream response
  703 + if (true) {
  704 + SrsMessage* msg = new SrsMessage();
  705 + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id);
  706 +
  707 + msg->set_packet(pkt, 0);
  708 +
  709 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  710 + srs_error("send releaseStream response message failed. ret=%d", ret);
  711 + return ret;
  712 + }
  713 + srs_info("send releaseStream response message success.");
640 } 714 }
641 715
642 return ret; 716 return ret;
@@ -35,6 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -35,6 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 #include <st.h> 35 #include <st.h>
36 36
37 class SrsProtocol; 37 class SrsProtocol;
  38 +class SrsMessage;
38 class SrsCreateStreamPacket; 39 class SrsCreateStreamPacket;
39 class SrsFMLEStartPacket; 40 class SrsFMLEStartPacket;
40 41
@@ -64,6 +65,17 @@ struct SrsRequest @@ -64,6 +65,17 @@ struct SrsRequest
64 }; 65 };
65 66
66 /** 67 /**
  68 +* the response to client.
  69 +*/
  70 +struct SrsResponse
  71 +{
  72 + int stream_id;
  73 +
  74 + SrsResponse();
  75 + virtual ~SrsResponse();
  76 +};
  77 +
  78 +/**
67 * the rtmp client type. 79 * the rtmp client type.
68 */ 80 */
69 enum SrsClientType 81 enum SrsClientType
@@ -88,6 +100,7 @@ public: @@ -88,6 +100,7 @@ public:
88 virtual ~SrsRtmp(); 100 virtual ~SrsRtmp();
89 public: 101 public:
90 virtual int handshake(); 102 virtual int handshake();
  103 + virtual int recv_message(SrsMessage** pmsg);
91 virtual int connect_app(SrsRequest* req); 104 virtual int connect_app(SrsRequest* req);
92 virtual int set_window_ack_size(int ack_size); 105 virtual int set_window_ack_size(int ack_size);
93 /** 106 /**
@@ -116,9 +129,24 @@ public: @@ -116,9 +129,24 @@ public:
116 * onStatus(NetStream.Data.Start). 129 * onStatus(NetStream.Data.Start).
117 */ 130 */
118 virtual int start_play(int stream_id); 131 virtual int start_play(int stream_id);
  132 + /**
  133 + * when client type is publish, response with packets:
  134 + * releaseStream response
  135 + * FCPublish
  136 + * FCPublish response
  137 + * createStream response
  138 + * onFCPublish(NetStream.Publish.Start)
  139 + * onStatus(NetStream.Publish.Start)
  140 + */
  141 + virtual int start_publish(int stream_id);
  142 + /**
  143 + * process the FMLE unpublish event.
  144 + * @unpublish_tid the unpublish request transaction id.
  145 + */
  146 + virtual int fmle_unpublish(int stream_id, double unpublish_tid);
119 private: 147 private:
120 virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name); 148 virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name);
121 - virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id, SrsClientType& type, std::string& stream_name); 149 + virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, std::string& stream_name);
122 }; 150 };
123 151
124 #endif 152 #endif