winlin

refine the thread model for the retry threads

要显示太多修改。

为保证性能只显示 21 of 21+ 个文件。

@@ -81,11 +81,11 @@ vhost __defaultVhost__ { @@ -81,11 +81,11 @@ vhost __defaultVhost__ {
81 vhost dev { 81 vhost dev {
82 enabled on; 82 enabled on;
83 gop_cache on; 83 gop_cache on;
84 - hls on; 84 + hls off;
85 hls_path ./objs/nginx/html; 85 hls_path ./objs/nginx/html;
86 hls_fragment 5; 86 hls_fragment 5;
87 hls_window 30; 87 hls_window 30;
88 - #forward 127.0.0.1:19350; 88 + forward 127.0.0.1:19350;
89 http_hooks { 89 http_hooks {
90 enabled off; 90 enabled off;
91 on_connect http://127.0.0.1:8085/api/v1/clients; 91 on_connect http://127.0.0.1:8085/api/v1/clients;
@@ -96,7 +96,7 @@ vhost dev { @@ -96,7 +96,7 @@ vhost dev {
96 on_stop http://127.0.0.1:8085/api/v1/sessions; 96 on_stop http://127.0.0.1:8085/api/v1/sessions;
97 } 97 }
98 transcode { 98 transcode {
99 - enabled off; 99 + enabled on;
100 ffmpeg ./objs/ffmpeg/bin/ffmpeg; 100 ffmpeg ./objs/ffmpeg/bin/ffmpeg;
101 engine dev { 101 engine dev {
102 enabled on; 102 enabled on;
@@ -116,7 +116,7 @@ MODULE_FILES=("srs_core" "srs_core_log" "srs_core_server" @@ -116,7 +116,7 @@ MODULE_FILES=("srs_core" "srs_core_log" "srs_core_server"
116 "srs_core_handshake" "srs_core_pithy_print" 116 "srs_core_handshake" "srs_core_pithy_print"
117 "srs_core_config" "srs_core_refer" "srs_core_reload" 117 "srs_core_config" "srs_core_refer" "srs_core_reload"
118 "srs_core_hls" "srs_core_forward" "srs_core_encoder" 118 "srs_core_hls" "srs_core_forward" "srs_core_encoder"
119 - "srs_core_http") 119 + "srs_core_http" "srs_core_thread")
120 MODULE_DIR="src/core" . auto/modules.sh 120 MODULE_DIR="src/core" . auto/modules.sh
121 CORE_OBJS="${MODULE_OBJS[@]}" 121 CORE_OBJS="${MODULE_OBJS[@]}"
122 122
不能预览此文件类型
@@ -111,3 +111,17 @@ void srs_vhost_resolve(std::string& vhost, std::string& app) @@ -111,3 +111,17 @@ void srs_vhost_resolve(std::string& vhost, std::string& app)
111 } 111 }
112 } 112 }
113 } 113 }
  114 +
  115 +void srs_close_stfd(st_netfd_t& stfd)
  116 +{
  117 + if (stfd) {
  118 + int fd = st_netfd_fileno(stfd);
  119 + st_netfd_close(stfd);
  120 + stfd = NULL;
  121 +
  122 + // st does not close it sometimes,
  123 + // close it manually.
  124 + close(fd);
  125 + }
  126 +}
  127 +
@@ -46,6 +46,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -46,6 +46,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46 #include <stddef.h> 46 #include <stddef.h>
47 #include <sys/types.h> 47 #include <sys/types.h>
48 48
  49 +#include <st.h>
  50 +
49 // generated by configure. 51 // generated by configure.
50 #include <srs_auto_headers.hpp> 52 #include <srs_auto_headers.hpp>
51 53
@@ -102,4 +104,7 @@ extern std::string srs_dns_resolve(std::string host); @@ -102,4 +104,7 @@ extern std::string srs_dns_resolve(std::string host);
102 // app...vhost...request_vhost 104 // app...vhost...request_vhost
103 extern void srs_vhost_resolve(std::string& vhost, std::string& app); 105 extern void srs_vhost_resolve(std::string& vhost, std::string& app);
104 106
  107 +// close the netfd, and close the underlayer fd.
  108 +extern void srs_close_stfd(st_netfd_t& stfd);
  109 +
105 #endif 110 #endif
@@ -36,15 +36,7 @@ SrsConnection::SrsConnection(SrsServer* srs_server, st_netfd_t client_stfd) @@ -36,15 +36,7 @@ SrsConnection::SrsConnection(SrsServer* srs_server, st_netfd_t client_stfd)
36 36
37 SrsConnection::~SrsConnection() 37 SrsConnection::~SrsConnection()
38 { 38 {
39 - if (stfd) {  
40 - int fd = st_netfd_fileno(stfd);  
41 - st_netfd_close(stfd);  
42 - stfd = NULL;  
43 -  
44 - // st does not close it sometimes,  
45 - // close it manually.  
46 - close(fd);  
47 - } 39 + srs_close_stfd(stfd);
48 } 40 }
49 41
50 int SrsConnection::start() 42 int SrsConnection::start()
@@ -30,8 +30,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,8 +30,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 30
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
33 -#include <st.h>  
34 -  
35 class SrsServer; 33 class SrsServer;
36 class SrsConnection 34 class SrsConnection
37 { 35 {
@@ -483,52 +483,15 @@ void SrsFFMPEG::stop() @@ -483,52 +483,15 @@ void SrsFFMPEG::stop()
483 483
484 SrsEncoder::SrsEncoder() 484 SrsEncoder::SrsEncoder()
485 { 485 {
486 - tid = NULL;  
487 - loop = false; 486 + pthread = new SrsThread(this, SRS_ENCODER_SLEEP_MS);
  487 + pithy_print = new SrsPithyPrint(SRS_STAGE_ENCODER);
488 } 488 }
489 489
490 SrsEncoder::~SrsEncoder() 490 SrsEncoder::~SrsEncoder()
491 { 491 {
492 on_unpublish(); 492 on_unpublish();
493 -}  
494 -  
495 -int SrsEncoder::parse_scope_engines(SrsRequest* req)  
496 -{  
497 - int ret = ERROR_SUCCESS;  
498 493
499 - // parse all transcode engines.  
500 - SrsConfDirective* conf = NULL;  
501 -  
502 - // parse vhost scope engines  
503 - std::string scope = "";  
504 - if ((conf = config->get_transcode(req->vhost, scope)) != NULL) {  
505 - if ((ret = parse_transcode(req, conf)) != ERROR_SUCCESS) {  
506 - srs_error("parse vhost scope=%s transcode engines failed. "  
507 - "ret=%d", scope.c_str(), ret);  
508 - return ret;  
509 - }  
510 - }  
511 - // parse app scope engines  
512 - scope = req->app;  
513 - if ((conf = config->get_transcode(req->vhost, scope)) != NULL) {  
514 - if ((ret = parse_transcode(req, conf)) != ERROR_SUCCESS) {  
515 - srs_error("parse app scope=%s transcode engines failed. "  
516 - "ret=%d", scope.c_str(), ret);  
517 - return ret;  
518 - }  
519 - }  
520 - // parse stream scope engines  
521 - scope += "/";  
522 - scope += req->stream;  
523 - if ((conf = config->get_transcode(req->vhost, scope)) != NULL) {  
524 - if ((ret = parse_transcode(req, conf)) != ERROR_SUCCESS) {  
525 - srs_error("parse stream scope=%s transcode engines failed. "  
526 - "ret=%d", scope.c_str(), ret);  
527 - return ret;  
528 - }  
529 - }  
530 -  
531 - return ret; 494 + srs_freep(pthread);
532 } 495 }
533 496
534 int SrsEncoder::on_publish(SrsRequest* req) 497 int SrsEncoder::on_publish(SrsRequest* req)
@@ -539,6 +502,7 @@ int SrsEncoder::on_publish(SrsRequest* req) @@ -539,6 +502,7 @@ int SrsEncoder::on_publish(SrsRequest* req)
539 502
540 // ignore the loop encoder 503 // ignore the loop encoder
541 if (ret == ERROR_ENCODER_LOOP) { 504 if (ret == ERROR_ENCODER_LOOP) {
  505 + clear_engines();
542 ret = ERROR_SUCCESS; 506 ret = ERROR_SUCCESS;
543 } 507 }
544 508
@@ -548,9 +512,7 @@ int SrsEncoder::on_publish(SrsRequest* req) @@ -548,9 +512,7 @@ int SrsEncoder::on_publish(SrsRequest* req)
548 } 512 }
549 513
550 // start thread to run all encoding engines. 514 // start thread to run all encoding engines.
551 - srs_assert(!tid);  
552 - if((tid = st_thread_create(encoder_thread, this, 1, 0)) == NULL) {  
553 - ret = ERROR_ST_CREATE_FORWARD_THREAD; 515 + if ((ret = pthread->start()) != ERROR_SUCCESS) {
554 srs_error("st_thread_create failed. ret=%d", ret); 516 srs_error("st_thread_create failed. ret=%d", ret);
555 return ret; 517 return ret;
556 } 518 }
@@ -560,23 +522,58 @@ int SrsEncoder::on_publish(SrsRequest* req) @@ -560,23 +522,58 @@ int SrsEncoder::on_publish(SrsRequest* req)
560 522
561 void SrsEncoder::on_unpublish() 523 void SrsEncoder::on_unpublish()
562 { 524 {
563 - if (tid) {  
564 - loop = false;  
565 - st_thread_interrupt(tid);  
566 - st_thread_join(tid, NULL);  
567 - tid = NULL; 525 + pthread->stop();
  526 + clear_engines();
  527 +}
  528 +
  529 +int SrsEncoder::cycle()
  530 +{
  531 + int ret = ERROR_SUCCESS;
  532 +
  533 + std::vector<SrsFFMPEG*>::iterator it;
  534 + for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {
  535 + SrsFFMPEG* ffmpeg = *it;
  536 +
  537 + // start all ffmpegs.
  538 + if ((ret = ffmpeg->start()) != ERROR_SUCCESS) {
  539 + srs_error("ffmpeg start failed. ret=%d", ret);
  540 + return ret;
  541 + }
  542 +
  543 + // check ffmpeg status.
  544 + if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) {
  545 + srs_error("ffmpeg cycle failed. ret=%d", ret);
  546 + return ret;
  547 + }
568 } 548 }
569 549
570 - clear_engines(); 550 + // pithy print
  551 + encoder();
  552 + pithy_print->elapse(SRS_ENCODER_SLEEP_MS);
  553 +
  554 + return ret;
  555 +}
  556 +
  557 +void SrsEncoder::on_leave_loop()
  558 +{
  559 + // kill ffmpeg when finished and it alive
  560 + std::vector<SrsFFMPEG*>::iterator it;
  561 +
  562 + for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {
  563 + SrsFFMPEG* ffmpeg = *it;
  564 + ffmpeg->stop();
  565 + }
571 } 566 }
572 567
573 void SrsEncoder::clear_engines() 568 void SrsEncoder::clear_engines()
574 { 569 {
575 std::vector<SrsFFMPEG*>::iterator it; 570 std::vector<SrsFFMPEG*>::iterator it;
  571 +
576 for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) { 572 for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {
577 SrsFFMPEG* ffmpeg = *it; 573 SrsFFMPEG* ffmpeg = *it;
578 srs_freep(ffmpeg); 574 srs_freep(ffmpeg);
579 } 575 }
  576 +
580 ffmpegs.clear(); 577 ffmpegs.clear();
581 } 578 }
582 579
@@ -585,6 +582,45 @@ SrsFFMPEG* SrsEncoder::at(int index) @@ -585,6 +582,45 @@ SrsFFMPEG* SrsEncoder::at(int index)
585 return ffmpegs[index]; 582 return ffmpegs[index];
586 } 583 }
587 584
  585 +int SrsEncoder::parse_scope_engines(SrsRequest* req)
  586 +{
  587 + int ret = ERROR_SUCCESS;
  588 +
  589 + // parse all transcode engines.
  590 + SrsConfDirective* conf = NULL;
  591 +
  592 + // parse vhost scope engines
  593 + std::string scope = "";
  594 + if ((conf = config->get_transcode(req->vhost, scope)) != NULL) {
  595 + if ((ret = parse_transcode(req, conf)) != ERROR_SUCCESS) {
  596 + srs_error("parse vhost scope=%s transcode engines failed. "
  597 + "ret=%d", scope.c_str(), ret);
  598 + return ret;
  599 + }
  600 + }
  601 + // parse app scope engines
  602 + scope = req->app;
  603 + if ((conf = config->get_transcode(req->vhost, scope)) != NULL) {
  604 + if ((ret = parse_transcode(req, conf)) != ERROR_SUCCESS) {
  605 + srs_error("parse app scope=%s transcode engines failed. "
  606 + "ret=%d", scope.c_str(), ret);
  607 + return ret;
  608 + }
  609 + }
  610 + // parse stream scope engines
  611 + scope += "/";
  612 + scope += req->stream;
  613 + if ((conf = config->get_transcode(req->vhost, scope)) != NULL) {
  614 + if ((ret = parse_transcode(req, conf)) != ERROR_SUCCESS) {
  615 + srs_error("parse stream scope=%s transcode engines failed. "
  616 + "ret=%d", scope.c_str(), ret);
  617 + return ret;
  618 + }
  619 + }
  620 +
  621 + return ret;
  622 +}
  623 +
588 int SrsEncoder::parse_transcode(SrsRequest* req, SrsConfDirective* conf) 624 int SrsEncoder::parse_transcode(SrsRequest* req, SrsConfDirective* conf)
589 { 625 {
590 int ret = ERROR_SUCCESS; 626 int ret = ERROR_SUCCESS;
@@ -631,7 +667,6 @@ int SrsEncoder::parse_transcode(SrsRequest* req, SrsConfDirective* conf) @@ -631,7 +667,6 @@ int SrsEncoder::parse_transcode(SrsRequest* req, SrsConfDirective* conf)
631 667
632 // if got a loop, donot transcode the whole stream. 668 // if got a loop, donot transcode the whole stream.
633 if (ret == ERROR_ENCODER_LOOP) { 669 if (ret == ERROR_ENCODER_LOOP) {
634 - clear_engines();  
635 break; 670 break;
636 } 671 }
637 672
@@ -646,85 +681,14 @@ int SrsEncoder::parse_transcode(SrsRequest* req, SrsConfDirective* conf) @@ -646,85 +681,14 @@ int SrsEncoder::parse_transcode(SrsRequest* req, SrsConfDirective* conf)
646 return ret; 681 return ret;
647 } 682 }
648 683
649 -int SrsEncoder::cycle()  
650 -{  
651 - int ret = ERROR_SUCCESS;  
652 -  
653 - std::vector<SrsFFMPEG*>::iterator it;  
654 - for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {  
655 - SrsFFMPEG* ffmpeg = *it;  
656 -  
657 - // start all ffmpegs.  
658 - if ((ret = ffmpeg->start()) != ERROR_SUCCESS) {  
659 - srs_error("ffmpeg start failed. ret=%d", ret);  
660 - return ret;  
661 - }  
662 -  
663 - // check ffmpeg status.  
664 - if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) {  
665 - srs_error("ffmpeg cycle failed. ret=%d", ret);  
666 - return ret;  
667 - }  
668 - }  
669 -  
670 - return ret;  
671 -}  
672 -  
673 -void SrsEncoder::encoder_cycle()  
674 -{  
675 - int ret = ERROR_SUCCESS;  
676 -  
677 - log_context->generate_id();  
678 - srs_trace("encoder cycle start");  
679 -  
680 - SrsPithyPrint pithy_print(SRS_STAGE_ENCODER);  
681 -  
682 - while (loop) {  
683 - if ((ret = cycle()) != ERROR_SUCCESS) {  
684 - srs_warn("encoder cycle failed, ignored and retry, ret=%d", ret);  
685 - } else {  
686 - srs_info("encoder cycle success, retry");  
687 - }  
688 -  
689 - if (!loop) {  
690 - break;  
691 - }  
692 -  
693 - encoder(&pithy_print);  
694 - pithy_print.elapse(SRS_ENCODER_SLEEP_MS);  
695 -  
696 - st_usleep(SRS_ENCODER_SLEEP_MS * 1000);  
697 - }  
698 -  
699 - // kill ffmpeg when finished and it alive  
700 - std::vector<SrsFFMPEG*>::iterator it;  
701 - for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {  
702 - SrsFFMPEG* ffmpeg = *it;  
703 - ffmpeg->stop();  
704 - }  
705 -  
706 - srs_trace("encoder cycle finished");  
707 -}  
708 -  
709 -void SrsEncoder::encoder(SrsPithyPrint* pithy_print) 684 +void SrsEncoder::encoder()
710 { 685 {
711 // reportable 686 // reportable
712 if (pithy_print->can_print()) { 687 if (pithy_print->can_print()) {
713 - srs_trace("-> time=%"PRId64", encoders=%d",  
714 - pithy_print->get_age(), (int)ffmpegs.size()); 688 + // TODO: FIXME: show more info.
  689 + srs_trace("-> time=%"PRId64", encoders=%d", pithy_print->get_age(), (int)ffmpegs.size());
715 } 690 }
716 } 691 }
717 692
718 -void* SrsEncoder::encoder_thread(void* arg)  
719 -{  
720 - SrsEncoder* obj = (SrsEncoder*)arg;  
721 - srs_assert(obj != NULL);  
722 -  
723 - obj->loop = true;  
724 - obj->encoder_cycle();  
725 -  
726 - return NULL;  
727 -}  
728 -  
729 #endif 693 #endif
730 694
@@ -32,7 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -32,7 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #include <string> 32 #include <string>
33 #include <vector> 33 #include <vector>
34 34
35 -#include <st.h> 35 +#include <srs_core_thread.hpp>
36 36
37 class SrsConfDirective; 37 class SrsConfDirective;
38 class SrsRequest; 38 class SrsRequest;
@@ -85,28 +85,29 @@ public: @@ -85,28 +85,29 @@ public:
85 * the encoder for a stream, 85 * the encoder for a stream,
86 * may use multiple ffmpegs to transcode the specified stream. 86 * may use multiple ffmpegs to transcode the specified stream.
87 */ 87 */
88 -class SrsEncoder 88 +class SrsEncoder : public ISrsThreadHandler
89 { 89 {
90 private: 90 private:
91 std::vector<SrsFFMPEG*> ffmpegs; 91 std::vector<SrsFFMPEG*> ffmpegs;
92 private: 92 private:
93 - st_thread_t tid;  
94 - bool loop; 93 + SrsThread* pthread;
  94 + SrsPithyPrint* pithy_print;
95 public: 95 public:
96 SrsEncoder(); 96 SrsEncoder();
97 virtual ~SrsEncoder(); 97 virtual ~SrsEncoder();
98 public: 98 public:
99 virtual int on_publish(SrsRequest* req); 99 virtual int on_publish(SrsRequest* req);
100 virtual void on_unpublish(); 100 virtual void on_unpublish();
  101 +// interface ISrsThreadHandler.
  102 +public:
  103 + virtual int cycle();
  104 + virtual void on_leave_loop();
101 private: 105 private:
102 - virtual int parse_scope_engines(SrsRequest* req);  
103 virtual void clear_engines(); 106 virtual void clear_engines();
104 virtual SrsFFMPEG* at(int index); 107 virtual SrsFFMPEG* at(int index);
  108 + virtual int parse_scope_engines(SrsRequest* req);
105 virtual int parse_transcode(SrsRequest* req, SrsConfDirective* conf); 109 virtual int parse_transcode(SrsRequest* req, SrsConfDirective* conf);
106 - virtual int cycle();  
107 - virtual void encoder_cycle();  
108 - virtual void encoder(SrsPithyPrint* pithy_print);  
109 - static void* encoder_thread(void* arg); 110 + virtual void encoder();
110 }; 111 };
111 112
112 #endif 113 #endif
@@ -37,8 +37,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -37,8 +37,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 #define ERROR_ST_OPEN_SOCKET 102 37 #define ERROR_ST_OPEN_SOCKET 102
38 #define ERROR_ST_CREATE_LISTEN_THREAD 103 38 #define ERROR_ST_CREATE_LISTEN_THREAD 103
39 #define ERROR_ST_CREATE_CYCLE_THREAD 104 39 #define ERROR_ST_CREATE_CYCLE_THREAD 104
40 -#define ERROR_ST_CREATE_FORWARD_THREAD 105  
41 -#define ERROR_ST_CONNECT 106 40 +#define ERROR_ST_CONNECT 105
42 41
43 #define ERROR_SOCKET_CREATE 200 42 #define ERROR_SOCKET_CREATE 200
44 #define ERROR_SOCKET_SETREUSE 201 43 #define ERROR_SOCKET_SETREUSE 201
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#include <srs_core_forward.hpp>  
25 -  
26 -#include <stdlib.h>  
27 -#include <sys/socket.h>  
28 -#include <netinet/in.h>  
29 -#include <arpa/inet.h>  
30 -  
31 -#include <srs_core_error.hpp>  
32 -#include <srs_core_rtmp.hpp>  
33 -#include <srs_core_log.hpp>  
34 -#include <srs_core_protocol.hpp>  
35 -#include <srs_core_pithy_print.hpp>  
36 -#include <srs_core_rtmp.hpp>  
37 -#include <srs_core_config.hpp>  
38 -  
39 -#define SRS_PULSE_TIMEOUT_MS 100  
40 -#define SRS_FORWARDER_SLEEP_MS 2000  
41 -#define SRS_SEND_TIMEOUT_US 3000000L  
42 -#define SRS_RECV_TIMEOUT_US SRS_SEND_TIMEOUT_US  
43 -  
44 -SrsForwarder::SrsForwarder()  
45 -{  
46 - client = NULL;  
47 - stfd = NULL;  
48 - stream_id = 0;  
49 -  
50 - tid = NULL;  
51 - loop = false;  
52 -}  
53 -  
54 -SrsForwarder::~SrsForwarder()  
55 -{  
56 - on_unpublish();  
57 -  
58 - std::vector<SrsSharedPtrMessage*>::iterator it;  
59 - for (it = msgs.begin(); it != msgs.end(); ++it) {  
60 - SrsSharedPtrMessage* msg = *it;  
61 - srs_freep(msg);  
62 - }  
63 - msgs.clear();  
64 -}  
65 -  
66 -int SrsForwarder::on_publish(SrsRequest* req, std::string forward_server)  
67 -{  
68 - int ret = ERROR_SUCCESS;  
69 -  
70 - // forward app  
71 - app = req->app;  
72 -  
73 - stream_name = req->stream;  
74 - server = forward_server;  
75 - std::string s_port = RTMP_DEFAULT_PORTS;  
76 - port = RTMP_DEFAULT_PORT;  
77 -  
78 - size_t pos = forward_server.find(":");  
79 - if (pos != std::string::npos) {  
80 - s_port = forward_server.substr(pos + 1);  
81 - server = forward_server.substr(0, pos);  
82 - }  
83 - // discovery vhost  
84 - std::string vhost = req->vhost;  
85 - srs_vhost_resolve(vhost, s_port);  
86 - port = ::atoi(s_port.c_str());  
87 -  
88 - // generate tcUrl  
89 - tc_url = "rtmp://";  
90 - tc_url += vhost;  
91 - tc_url += "/";  
92 - tc_url += req->app;  
93 -  
94 - // dead loop check  
95 - std::string source_ep = req->vhost;  
96 - source_ep += ":";  
97 - source_ep += req->port;  
98 -  
99 - std::string dest_ep = vhost;  
100 - dest_ep += ":";  
101 - dest_ep += s_port;  
102 -  
103 - if (source_ep == dest_ep) {  
104 - ret = ERROR_SYSTEM_FORWARD_LOOP;  
105 - srs_warn("farder loop detected. src=%s, dest=%s, ret=%d",  
106 - source_ep.c_str(), dest_ep.c_str(), ret);  
107 - return ret;  
108 - }  
109 - srs_trace("start forward %s to %s, stream: %s/%s",  
110 - source_ep.c_str(), dest_ep.c_str(), tc_url.c_str(),  
111 - stream_name.c_str());  
112 -  
113 - // TODO: seems bug when republish and reforward.  
114 -  
115 - // start forward  
116 - if ((ret = open_socket()) != ERROR_SUCCESS) {  
117 - return ret;  
118 - }  
119 -  
120 - srs_assert(!tid);  
121 - if((tid = st_thread_create(forward_thread, this, 1, 0)) == NULL){  
122 - ret = ERROR_ST_CREATE_FORWARD_THREAD;  
123 - srs_error("st_thread_create failed. ret=%d", ret);  
124 - return ret;  
125 - }  
126 -  
127 - return ret;  
128 -}  
129 -  
130 -void SrsForwarder::on_unpublish()  
131 -{  
132 - if (tid) {  
133 - loop = false;  
134 - st_thread_interrupt(tid);  
135 - st_thread_join(tid, NULL);  
136 - tid = NULL;  
137 - }  
138 -  
139 - if (stfd) {  
140 - int fd = st_netfd_fileno(stfd);  
141 - st_netfd_close(stfd);  
142 - stfd = NULL;  
143 -  
144 - // st does not close it sometimes,  
145 - // close it manually.  
146 - close(fd);  
147 - }  
148 -  
149 - srs_freep(client);  
150 -}  
151 -  
152 -int SrsForwarder::on_meta_data(SrsSharedPtrMessage* metadata)  
153 -{  
154 - int ret = ERROR_SUCCESS;  
155 -  
156 - msgs.push_back(metadata);  
157 -  
158 - return ret;  
159 -}  
160 -  
161 -int SrsForwarder::on_audio(SrsSharedPtrMessage* msg)  
162 -{  
163 - int ret = ERROR_SUCCESS;  
164 -  
165 - // TODO: FIXME: must drop the msgs when server failed.  
166 - msgs.push_back(msg);  
167 -  
168 - return ret;  
169 -}  
170 -  
171 -int SrsForwarder::on_video(SrsSharedPtrMessage* msg)  
172 -{  
173 - int ret = ERROR_SUCCESS;  
174 -  
175 - // TODO: FIXME: must drop the msgs when server failed.  
176 - msgs.push_back(msg);  
177 -  
178 - return ret;  
179 -}  
180 -  
181 -int SrsForwarder::open_socket()  
182 -{  
183 - int ret = ERROR_SUCCESS;  
184 -  
185 - srs_trace("forward stream=%s, tcUrl=%s to server=%s, port=%d",  
186 - stream_name.c_str(), tc_url.c_str(), server.c_str(), port);  
187 -  
188 - int sock = socket(AF_INET, SOCK_STREAM, 0);  
189 - if(sock == -1){  
190 - ret = ERROR_SOCKET_CREATE;  
191 - srs_error("create socket error. ret=%d", ret);  
192 - return ret;  
193 - }  
194 -  
195 - stfd = st_netfd_open_socket(sock);  
196 - if(stfd == NULL){  
197 - ret = ERROR_ST_OPEN_SOCKET;  
198 - srs_error("st_netfd_open_socket failed. ret=%d", ret);  
199 - return ret;  
200 - }  
201 -  
202 - srs_freep(client);  
203 - client = new SrsRtmpClient(stfd);  
204 -  
205 - return ret;  
206 -}  
207 -  
208 -int SrsForwarder::connect_server()  
209 -{  
210 - int ret = ERROR_SUCCESS;  
211 -  
212 - std::string ip = srs_dns_resolve(server);  
213 - if (ip.empty()) {  
214 - ret = ERROR_SYSTEM_IP_INVALID;  
215 - srs_error("dns resolve server error, ip empty. ret=%d", ret);  
216 - return ret;  
217 - }  
218 -  
219 - sockaddr_in addr;  
220 - addr.sin_family = AF_INET;  
221 - addr.sin_port = htons(port);  
222 - addr.sin_addr.s_addr = inet_addr(ip.c_str());  
223 -  
224 - if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){  
225 - ret = ERROR_ST_CONNECT;  
226 - srs_error("connect to server error. ip=%s, port=%d, ret=%d", ip.c_str(), port, ret);  
227 - return ret;  
228 - }  
229 - srs_trace("connect to server success. server=%s, ip=%s, port=%d", server.c_str(), ip.c_str(), port);  
230 -  
231 - return ret;  
232 -}  
233 -  
234 -int SrsForwarder::cycle()  
235 -{  
236 - int ret = ERROR_SUCCESS;  
237 -  
238 - client->set_recv_timeout(SRS_RECV_TIMEOUT_US);  
239 - client->set_send_timeout(SRS_SEND_TIMEOUT_US);  
240 -  
241 - if ((ret = connect_server()) != ERROR_SUCCESS) {  
242 - return ret;  
243 - }  
244 - srs_assert(client);  
245 -  
246 - if ((ret = client->handshake()) != ERROR_SUCCESS) {  
247 - srs_error("handshake with server failed. ret=%d", ret);  
248 - return ret;  
249 - }  
250 - if ((ret = client->connect_app(app, tc_url)) != ERROR_SUCCESS) {  
251 - srs_error("connect with server failed, tcUrl=%s. ret=%d", tc_url.c_str(), ret);  
252 - return ret;  
253 - }  
254 - if ((ret = client->create_stream(stream_id)) != ERROR_SUCCESS) {  
255 - srs_error("connect with server failed, stream_id=%d. ret=%d", stream_id, ret);  
256 - return ret;  
257 - }  
258 -  
259 - // TODO: FIXME: need to cache the metadata and sequence header when reconnect.  
260 -  
261 - if ((ret = client->publish(stream_name, stream_id)) != ERROR_SUCCESS) {  
262 - srs_error("connect with server failed, stream_name=%s, stream_id=%d. ret=%d",  
263 - stream_name.c_str(), stream_id, ret);  
264 - return ret;  
265 - }  
266 -  
267 - if ((ret = forward()) != ERROR_SUCCESS) {  
268 - return ret;  
269 - }  
270 -  
271 - return ret;  
272 -}  
273 -  
274 -int SrsForwarder::forward()  
275 -{  
276 - int ret = ERROR_SUCCESS;  
277 -  
278 - client->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000);  
279 -  
280 - SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER);  
281 -  
282 - while (loop) {  
283 - pithy_print.elapse(SRS_PULSE_TIMEOUT_MS);  
284 -  
285 - // switch to other st-threads.  
286 - st_usleep(0);  
287 -  
288 - // read from client.  
289 - if (true) {  
290 - SrsCommonMessage* msg = NULL;  
291 - ret = client->recv_message(&msg);  
292 -  
293 - srs_verbose("play loop recv message. ret=%d", ret);  
294 - if (ret != ERROR_SUCCESS && ret != ERROR_SOCKET_TIMEOUT) {  
295 - srs_error("recv server control message failed. ret=%d", ret);  
296 - return ret;  
297 - }  
298 - }  
299 -  
300 - // ignore when no messages.  
301 - int count = (int)msgs.size();  
302 - if (msgs.empty()) {  
303 - continue;  
304 - }  
305 -  
306 - // reportable  
307 - if (pithy_print.can_print()) {  
308 - srs_trace("-> time=%"PRId64", msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",  
309 - pithy_print.get_age(), count, client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps());  
310 - }  
311 -  
312 - // all msgs to forward.  
313 - int i = 0;  
314 - for (i = 0; i < count; i++) {  
315 - SrsSharedPtrMessage* msg = msgs[i];  
316 - msgs[i] = NULL;  
317 -  
318 - // we erased the sendout messages, the msg must not be NULL.  
319 - srs_assert(msg);  
320 -  
321 - ret = client->send_message(msg);  
322 - if (ret != ERROR_SUCCESS) {  
323 - srs_error("forwarder send message to server failed. ret=%d", ret);  
324 -  
325 - // convert the index to count when error.  
326 - i++;  
327 -  
328 - break;  
329 - }  
330 - }  
331 -  
332 - // clear sendout mesages.  
333 - if (i < count) {  
334 - srs_warn("clear forwarded msg, total=%d, forwarded=%d, ret=%d", count, i, ret);  
335 - } else {  
336 - srs_info("clear forwarded msg, total=%d, forwarded=%d, ret=%d", count, i, ret);  
337 - }  
338 - msgs.erase(msgs.begin(), msgs.begin() + i);  
339 -  
340 - if (ret != ERROR_SUCCESS) {  
341 - break;  
342 - }  
343 - }  
344 -  
345 - return ret;  
346 -}  
347 -  
348 -void SrsForwarder::forward_cycle()  
349 -{  
350 - int ret = ERROR_SUCCESS;  
351 -  
352 - log_context->generate_id();  
353 - srs_trace("forward cycle start");  
354 -  
355 - while (loop) {  
356 - if ((ret = cycle()) != ERROR_SUCCESS) {  
357 - srs_warn("forward cycle failed, ignored and retry, ret=%d", ret);  
358 - } else {  
359 - srs_info("forward cycle success, retry");  
360 - }  
361 -  
362 - if (!loop) {  
363 - break;  
364 - }  
365 -  
366 - st_usleep(SRS_FORWARDER_SLEEP_MS * 1000);  
367 -  
368 - if ((ret = open_socket()) != ERROR_SUCCESS) {  
369 - srs_warn("forward cycle reopen failed, ignored and retry, ret=%d", ret);  
370 - } else {  
371 - srs_info("forward cycle reopen success");  
372 - }  
373 - }  
374 - srs_trace("forward cycle finished");  
375 -}  
376 -  
377 -void* SrsForwarder::forward_thread(void* arg)  
378 -{  
379 - SrsForwarder* obj = (SrsForwarder*)arg;  
380 - srs_assert(obj != NULL);  
381 -  
382 - obj->loop = true;  
383 - obj->forward_cycle();  
384 -  
385 - return NULL;  
386 -}  
387 - 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_forward.hpp>
  25 +
  26 +#include <stdlib.h>
  27 +#include <sys/socket.h>
  28 +#include <netinet/in.h>
  29 +#include <arpa/inet.h>
  30 +
  31 +#include <srs_core_error.hpp>
  32 +#include <srs_core_rtmp.hpp>
  33 +#include <srs_core_log.hpp>
  34 +#include <srs_core_protocol.hpp>
  35 +#include <srs_core_pithy_print.hpp>
  36 +#include <srs_core_rtmp.hpp>
  37 +#include <srs_core_config.hpp>
  38 +
  39 +#define SRS_PULSE_TIMEOUT_MS 100
  40 +#define SRS_FORWARDER_SLEEP_MS 2000
  41 +#define SRS_SEND_TIMEOUT_US 3000000L
  42 +#define SRS_RECV_TIMEOUT_US SRS_SEND_TIMEOUT_US
  43 +
  44 +SrsForwarder::SrsForwarder()
  45 +{
  46 + client = NULL;
  47 + stfd = NULL;
  48 + stream_id = 0;
  49 +
  50 + pthread = new SrsThread(this, SRS_FORWARDER_SLEEP_MS);
  51 +}
  52 +
  53 +SrsForwarder::~SrsForwarder()
  54 +{
  55 + on_unpublish();
  56 +
  57 + std::vector<SrsSharedPtrMessage*>::iterator it;
  58 + for (it = msgs.begin(); it != msgs.end(); ++it) {
  59 + SrsSharedPtrMessage* msg = *it;
  60 + srs_freep(msg);
  61 + }
  62 + msgs.clear();
  63 +
  64 + srs_freep(pthread);
  65 +}
  66 +
  67 +int SrsForwarder::on_publish(SrsRequest* req, std::string forward_server)
  68 +{
  69 + int ret = ERROR_SUCCESS;
  70 +
  71 + // forward app
  72 + app = req->app;
  73 +
  74 + stream_name = req->stream;
  75 + server = forward_server;
  76 + std::string s_port = RTMP_DEFAULT_PORTS;
  77 + port = RTMP_DEFAULT_PORT;
  78 +
  79 + size_t pos = forward_server.find(":");
  80 + if (pos != std::string::npos) {
  81 + s_port = forward_server.substr(pos + 1);
  82 + server = forward_server.substr(0, pos);
  83 + }
  84 + // discovery vhost
  85 + std::string vhost = req->vhost;
  86 + srs_vhost_resolve(vhost, s_port);
  87 + port = ::atoi(s_port.c_str());
  88 +
  89 + // generate tcUrl
  90 + tc_url = "rtmp://";
  91 + tc_url += vhost;
  92 + tc_url += "/";
  93 + tc_url += req->app;
  94 +
  95 + // dead loop check
  96 + std::string source_ep = req->vhost;
  97 + source_ep += ":";
  98 + source_ep += req->port;
  99 +
  100 + std::string dest_ep = vhost;
  101 + dest_ep += ":";
  102 + dest_ep += s_port;
  103 +
  104 + if (source_ep == dest_ep) {
  105 + ret = ERROR_SYSTEM_FORWARD_LOOP;
  106 + srs_warn("farder loop detected. src=%s, dest=%s, ret=%d",
  107 + source_ep.c_str(), dest_ep.c_str(), ret);
  108 + return ret;
  109 + }
  110 + srs_trace("start forward %s to %s, stream: %s/%s",
  111 + source_ep.c_str(), dest_ep.c_str(), tc_url.c_str(),
  112 + stream_name.c_str());
  113 +
  114 + if ((ret = pthread->start()) != ERROR_SUCCESS) {
  115 + srs_error("start srs thread failed. ret=%d", ret);
  116 + return ret;
  117 + }
  118 +
  119 + return ret;
  120 +}
  121 +
  122 +void SrsForwarder::on_unpublish()
  123 +{
  124 + pthread->stop();
  125 +
  126 + close_underlayer_socket();
  127 +
  128 + srs_freep(client);
  129 +}
  130 +
  131 +int SrsForwarder::on_meta_data(SrsSharedPtrMessage* metadata)
  132 +{
  133 + int ret = ERROR_SUCCESS;
  134 +
  135 + msgs.push_back(metadata);
  136 +
  137 + return ret;
  138 +}
  139 +
  140 +int SrsForwarder::on_audio(SrsSharedPtrMessage* msg)
  141 +{
  142 + int ret = ERROR_SUCCESS;
  143 +
  144 + // TODO: FIXME: must drop the msgs when server failed.
  145 + msgs.push_back(msg);
  146 +
  147 + return ret;
  148 +}
  149 +
  150 +int SrsForwarder::on_video(SrsSharedPtrMessage* msg)
  151 +{
  152 + int ret = ERROR_SUCCESS;
  153 +
  154 + // TODO: FIXME: must drop the msgs when server failed.
  155 + msgs.push_back(msg);
  156 +
  157 + return ret;
  158 +}
  159 +
  160 +int SrsForwarder::cycle()
  161 +{
  162 + int ret = ERROR_SUCCESS;
  163 +
  164 + if ((ret = connect_server()) != ERROR_SUCCESS) {
  165 + return ret;
  166 + }
  167 + srs_assert(client);
  168 +
  169 + client->set_recv_timeout(SRS_RECV_TIMEOUT_US);
  170 + client->set_send_timeout(SRS_SEND_TIMEOUT_US);
  171 +
  172 + if ((ret = client->handshake()) != ERROR_SUCCESS) {
  173 + srs_error("handshake with server failed. ret=%d", ret);
  174 + return ret;
  175 + }
  176 + if ((ret = client->connect_app(app, tc_url)) != ERROR_SUCCESS) {
  177 + srs_error("connect with server failed, tcUrl=%s. ret=%d", tc_url.c_str(), ret);
  178 + return ret;
  179 + }
  180 + if ((ret = client->create_stream(stream_id)) != ERROR_SUCCESS) {
  181 + srs_error("connect with server failed, stream_id=%d. ret=%d", stream_id, ret);
  182 + return ret;
  183 + }
  184 +
  185 + // TODO: FIXME: need to cache the metadata and sequence header when reconnect.
  186 +
  187 + if ((ret = client->publish(stream_name, stream_id)) != ERROR_SUCCESS) {
  188 + srs_error("connect with server failed, stream_name=%s, stream_id=%d. ret=%d",
  189 + stream_name.c_str(), stream_id, ret);
  190 + return ret;
  191 + }
  192 +
  193 + if ((ret = forward()) != ERROR_SUCCESS) {
  194 + return ret;
  195 + }
  196 +
  197 + return ret;
  198 +}
  199 +
  200 +void SrsForwarder::close_underlayer_socket()
  201 +{
  202 + srs_close_stfd(stfd);
  203 +}
  204 +
  205 +int SrsForwarder::connect_server()
  206 +{
  207 + int ret = ERROR_SUCCESS;
  208 +
  209 + // reopen
  210 + close_underlayer_socket();
  211 +
  212 + // open socket.
  213 + srs_trace("forward stream=%s, tcUrl=%s to server=%s, port=%d",
  214 + stream_name.c_str(), tc_url.c_str(), server.c_str(), port);
  215 +
  216 + int sock = socket(AF_INET, SOCK_STREAM, 0);
  217 + if(sock == -1){
  218 + ret = ERROR_SOCKET_CREATE;
  219 + srs_error("create socket error. ret=%d", ret);
  220 + return ret;
  221 + }
  222 +
  223 + srs_assert(!stfd);
  224 + stfd = st_netfd_open_socket(sock);
  225 + if(stfd == NULL){
  226 + ret = ERROR_ST_OPEN_SOCKET;
  227 + srs_error("st_netfd_open_socket failed. ret=%d", ret);
  228 + return ret;
  229 + }
  230 +
  231 + srs_freep(client);
  232 + client = new SrsRtmpClient(stfd);
  233 +
  234 + // connect to server.
  235 + std::string ip = srs_dns_resolve(server);
  236 + if (ip.empty()) {
  237 + ret = ERROR_SYSTEM_IP_INVALID;
  238 + srs_error("dns resolve server error, ip empty. ret=%d", ret);
  239 + return ret;
  240 + }
  241 +
  242 + sockaddr_in addr;
  243 + addr.sin_family = AF_INET;
  244 + addr.sin_port = htons(port);
  245 + addr.sin_addr.s_addr = inet_addr(ip.c_str());
  246 +
  247 + if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){
  248 + ret = ERROR_ST_CONNECT;
  249 + srs_error("connect to server error. ip=%s, port=%d, ret=%d", ip.c_str(), port, ret);
  250 + return ret;
  251 + }
  252 + srs_trace("connect to server success. server=%s, ip=%s, port=%d", server.c_str(), ip.c_str(), port);
  253 +
  254 + return ret;
  255 +}
  256 +
  257 +int SrsForwarder::forward()
  258 +{
  259 + int ret = ERROR_SUCCESS;
  260 +
  261 + client->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000);
  262 +
  263 + SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER);
  264 +
  265 + while (true) {
  266 + // switch to other st-threads.
  267 + st_usleep(0);
  268 +
  269 + // read from client.
  270 + if (true) {
  271 + SrsCommonMessage* msg = NULL;
  272 + ret = client->recv_message(&msg);
  273 +
  274 + srs_verbose("play loop recv message. ret=%d", ret);
  275 + if (ret != ERROR_SUCCESS && ret != ERROR_SOCKET_TIMEOUT) {
  276 + srs_error("recv server control message failed. ret=%d", ret);
  277 + return ret;
  278 + }
  279 + }
  280 +
  281 + // ignore when no messages.
  282 + int count = (int)msgs.size();
  283 + if (msgs.empty()) {
  284 + continue;
  285 + }
  286 +
  287 + // pithy print
  288 + pithy_print.elapse(SRS_PULSE_TIMEOUT_MS);
  289 + if (pithy_print.can_print()) {
  290 + srs_trace("-> time=%"PRId64", msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",
  291 + pithy_print.get_age(), count, client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps());
  292 + }
  293 +
  294 + // all msgs to forward.
  295 + int i = 0;
  296 + for (i = 0; i < count; i++) {
  297 + SrsSharedPtrMessage* msg = msgs[i];
  298 + msgs[i] = NULL;
  299 +
  300 + // we erased the sendout messages, the msg must not be NULL.
  301 + srs_assert(msg);
  302 +
  303 + ret = client->send_message(msg);
  304 + if (ret != ERROR_SUCCESS) {
  305 + srs_error("forwarder send message to server failed. ret=%d", ret);
  306 +
  307 + // convert the index to count when error.
  308 + i++;
  309 +
  310 + break;
  311 + }
  312 + }
  313 +
  314 + // clear sendout mesages.
  315 + if (i < count) {
  316 + srs_warn("clear forwarded msg, total=%d, forwarded=%d, ret=%d", count, i, ret);
  317 + } else {
  318 + srs_info("clear forwarded msg, total=%d, forwarded=%d, ret=%d", count, i, ret);
  319 + }
  320 + msgs.erase(msgs.begin(), msgs.begin() + i);
  321 +
  322 + if (ret != ERROR_SUCCESS) {
  323 + break;
  324 + }
  325 + }
  326 +
  327 + return ret;
  328 +}
  329 +
@@ -32,7 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -32,7 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #include <string> 32 #include <string>
33 #include <vector> 33 #include <vector>
34 34
35 -#include <st.h> 35 +#include <srs_core_thread.hpp>
36 36
37 class SrsSharedPtrMessage; 37 class SrsSharedPtrMessage;
38 class SrsOnMetaDataPacket; 38 class SrsOnMetaDataPacket;
@@ -42,7 +42,7 @@ class SrsRequest; @@ -42,7 +42,7 @@ class SrsRequest;
42 /** 42 /**
43 * forward the stream to other servers. 43 * forward the stream to other servers.
44 */ 44 */
45 -class SrsForwarder 45 +class SrsForwarder : public ISrsThreadHandler
46 { 46 {
47 private: 47 private:
48 std::string app; 48 std::string app;
@@ -53,8 +53,7 @@ private: @@ -53,8 +53,7 @@ private:
53 int port; 53 int port;
54 private: 54 private:
55 st_netfd_t stfd; 55 st_netfd_t stfd;
56 - st_thread_t tid;  
57 - bool loop; 56 + SrsThread* pthread;
58 private: 57 private:
59 SrsRtmpClient* client; 58 SrsRtmpClient* client;
60 std::vector<SrsSharedPtrMessage*> msgs; 59 std::vector<SrsSharedPtrMessage*> msgs;
@@ -67,14 +66,13 @@ public: @@ -67,14 +66,13 @@ public:
67 virtual int on_meta_data(SrsSharedPtrMessage* metadata); 66 virtual int on_meta_data(SrsSharedPtrMessage* metadata);
68 virtual int on_audio(SrsSharedPtrMessage* msg); 67 virtual int on_audio(SrsSharedPtrMessage* msg);
69 virtual int on_video(SrsSharedPtrMessage* msg); 68 virtual int on_video(SrsSharedPtrMessage* msg);
  69 +// interface ISrsThreadHandler.
  70 +public:
  71 + virtual int cycle();
70 private: 72 private:
71 - virtual int open_socket(); 73 + virtual void close_underlayer_socket();
72 virtual int connect_server(); 74 virtual int connect_server();
73 -private:  
74 - virtual int cycle();  
75 virtual int forward(); 75 virtual int forward();
76 - virtual void forward_cycle();  
77 - static void* forward_thread(void* arg);  
78 }; 76 };
79 77
80 #endif 78 #endif
@@ -184,15 +184,7 @@ void SrsHttpClient::disconnect() @@ -184,15 +184,7 @@ void SrsHttpClient::disconnect()
184 { 184 {
185 connected = false; 185 connected = false;
186 186
187 - if (stfd) {  
188 - int fd = st_netfd_fileno(stfd);  
189 - st_netfd_close(stfd);  
190 - stfd = NULL;  
191 -  
192 - // st does not close it sometimes,  
193 - // close it manually.  
194 - ::close(fd);  
195 - } 187 + srs_close_stfd(stfd);
196 } 188 }
197 189
198 int SrsHttpClient::connect(SrsHttpUri* uri) 190 int SrsHttpClient::connect(SrsHttpUri* uri)
@@ -36,7 +36,6 @@ class SrsSocket; @@ -36,7 +36,6 @@ class SrsSocket;
36 36
37 #include <string> 37 #include <string>
38 38
39 -#include <st.h>  
40 #include <http_parser.h> 39 #include <http_parser.h>
41 40
42 #define SRS_HTTP_HEADER_BUFFER 1024 41 #define SRS_HTTP_HEADER_BUFFER 1024
@@ -29,8 +29,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -29,8 +29,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #include <string> 29 #include <string>
30 #include <map> 30 #include <map>
31 31
32 -#include <st.h>  
33 -  
34 ILogContext::ILogContext() 32 ILogContext::ILogContext()
35 { 33 {
36 } 34 }
@@ -33,8 +33,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -33,8 +33,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 #include <map> 33 #include <map>
34 #include <string> 34 #include <string>
35 35
36 -#include <st.h>  
37 -  
38 #include <srs_core_log.hpp> 36 #include <srs_core_log.hpp>
39 #include <srs_core_error.hpp> 37 #include <srs_core_error.hpp>
40 38
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#include <srs_core_rtmp.hpp>  
25 -  
26 -#include <srs_core_log.hpp>  
27 -#include <srs_core_error.hpp>  
28 -#include <srs_core_socket.hpp>  
29 -#include <srs_core_protocol.hpp>  
30 -#include <srs_core_autofree.hpp>  
31 -#include <srs_core_amf0.hpp>  
32 -#include <srs_core_handshake.hpp>  
33 -#include <srs_core_config.hpp>  
34 -  
35 -/**  
36 -* the signature for packets to client.  
37 -*/  
38 -#define RTMP_SIG_FMS_VER "3,5,3,888"  
39 -#define RTMP_SIG_AMF0_VER 0  
40 -#define RTMP_SIG_CLIENT_ID "ASAICiss"  
41 -  
42 -/**  
43 -* onStatus consts.  
44 -*/  
45 -#define StatusLevel "level"  
46 -#define StatusCode "code"  
47 -#define StatusDescription "description"  
48 -#define StatusDetails "details"  
49 -#define StatusClientId "clientid"  
50 -// status value  
51 -#define StatusLevelStatus "status"  
52 -// code value  
53 -#define StatusCodeConnectSuccess "NetConnection.Connect.Success"  
54 -#define StatusCodeStreamReset "NetStream.Play.Reset"  
55 -#define StatusCodeStreamStart "NetStream.Play.Start"  
56 -#define StatusCodeStreamPause "NetStream.Pause.Notify"  
57 -#define StatusCodeStreamUnpause "NetStream.Unpause.Notify"  
58 -#define StatusCodePublishStart "NetStream.Publish.Start"  
59 -#define StatusCodeDataStart "NetStream.Data.Start"  
60 -#define StatusCodeUnpublishSuccess "NetStream.Unpublish.Success"  
61 -  
62 -// FMLE  
63 -#define RTMP_AMF0_COMMAND_ON_FC_PUBLISH "onFCPublish"  
64 -#define RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH "onFCUnpublish"  
65 -  
66 -// default stream id for response the createStream request.  
67 -#define SRS_DEFAULT_SID 1  
68 -  
69 -SrsRequest::SrsRequest()  
70 -{  
71 - objectEncoding = RTMP_SIG_AMF0_VER;  
72 -}  
73 -  
74 -SrsRequest::~SrsRequest()  
75 -{  
76 -}  
77 -  
78 -int SrsRequest::discovery_app()  
79 -{  
80 - int ret = ERROR_SUCCESS;  
81 -  
82 - size_t pos = std::string::npos;  
83 - std::string url = tcUrl;  
84 -  
85 - if ((pos = url.find("://")) != std::string::npos) {  
86 - schema = url.substr(0, pos);  
87 - url = url.substr(schema.length() + 3);  
88 - srs_verbose("discovery schema=%s", schema.c_str());  
89 - }  
90 -  
91 - if ((pos = url.find("/")) != std::string::npos) {  
92 - vhost = url.substr(0, pos);  
93 - url = url.substr(vhost.length() + 1);  
94 - srs_verbose("discovery vhost=%s", vhost.c_str());  
95 - }  
96 -  
97 - port = RTMP_DEFAULT_PORTS;  
98 - if ((pos = vhost.find(":")) != std::string::npos) {  
99 - port = vhost.substr(pos + 1);  
100 - vhost = vhost.substr(0, pos);  
101 - srs_verbose("discovery vhost=%s, port=%s", vhost.c_str(), port.c_str());  
102 - }  
103 -  
104 - app = url;  
105 - srs_vhost_resolve(vhost, app);  
106 -  
107 - // resolve the vhost from config  
108 - SrsConfDirective* parsed_vhost = config->get_vhost(vhost);  
109 - if (parsed_vhost) {  
110 - vhost = parsed_vhost->arg0();  
111 - }  
112 -  
113 - // TODO: discovery the params of vhost.  
114 -  
115 - srs_info("discovery app success. schema=%s, vhost=%s, port=%s, app=%s",  
116 - schema.c_str(), vhost.c_str(), port.c_str(), app.c_str());  
117 -  
118 - if (schema.empty() || vhost.empty() || port.empty() || app.empty()) {  
119 - ret = ERROR_RTMP_REQ_TCURL;  
120 - srs_error("discovery tcUrl failed. "  
121 - "tcUrl=%s, schema=%s, vhost=%s, port=%s, app=%s, ret=%d",  
122 - tcUrl.c_str(), schema.c_str(), vhost.c_str(), port.c_str(), app.c_str(), ret);  
123 - return ret;  
124 - }  
125 -  
126 - strip();  
127 -  
128 - return ret;  
129 -}  
130 -  
131 -std::string SrsRequest::get_stream_url()  
132 -{  
133 - std::string url = "";  
134 -  
135 - url += vhost;  
136 - url += "/";  
137 - url += app;  
138 - url += "/";  
139 - url += stream;  
140 -  
141 - return url;  
142 -}  
143 -  
144 -void SrsRequest::strip()  
145 -{  
146 - trim(vhost, "/ \n\r\t");  
147 - trim(app, "/ \n\r\t");  
148 - trim(stream, "/ \n\r\t");  
149 -}  
150 -  
151 -std::string& SrsRequest::trim(std::string& str, std::string chs)  
152 -{  
153 - for (int i = 0; i < (int)chs.length(); i++) {  
154 - char ch = chs.at(i);  
155 -  
156 - for (std::string::iterator it = str.begin(); it != str.end();) {  
157 - if (ch == *it) {  
158 - it = str.erase(it);  
159 - } else {  
160 - ++it;  
161 - }  
162 - }  
163 - }  
164 -  
165 - return str;  
166 -}  
167 -  
168 -SrsResponse::SrsResponse()  
169 -{  
170 - stream_id = SRS_DEFAULT_SID;  
171 -}  
172 -  
173 -SrsResponse::~SrsResponse()  
174 -{  
175 -}  
176 -  
177 -SrsRtmpClient::SrsRtmpClient(st_netfd_t _stfd)  
178 -{  
179 - stfd = _stfd;  
180 - protocol = new SrsProtocol(stfd);  
181 -}  
182 -  
183 -SrsRtmpClient::~SrsRtmpClient()  
184 -{  
185 - srs_freep(protocol);  
186 -}  
187 -  
188 -void SrsRtmpClient::set_recv_timeout(int64_t timeout_us)  
189 -{  
190 - protocol->set_recv_timeout(timeout_us);  
191 -}  
192 -  
193 -void SrsRtmpClient::set_send_timeout(int64_t timeout_us)  
194 -{  
195 - protocol->set_send_timeout(timeout_us);  
196 -}  
197 -  
198 -int64_t SrsRtmpClient::get_recv_bytes()  
199 -{  
200 - return protocol->get_recv_bytes();  
201 -}  
202 -  
203 -int64_t SrsRtmpClient::get_send_bytes()  
204 -{  
205 - return protocol->get_send_bytes();  
206 -}  
207 -  
208 -int SrsRtmpClient::get_recv_kbps()  
209 -{  
210 - return protocol->get_recv_kbps();  
211 -}  
212 -  
213 -int SrsRtmpClient::get_send_kbps()  
214 -{  
215 - return protocol->get_send_kbps();  
216 -}  
217 -  
218 -int SrsRtmpClient::recv_message(SrsCommonMessage** pmsg)  
219 -{  
220 - return protocol->recv_message(pmsg);  
221 -}  
222 -  
223 -int SrsRtmpClient::send_message(ISrsMessage* msg)  
224 -{  
225 - return protocol->send_message(msg);  
226 -}  
227 -  
228 -int SrsRtmpClient::handshake()  
229 -{  
230 - int ret = ERROR_SUCCESS;  
231 -  
232 - SrsSocket skt(stfd);  
233 -  
234 - SrsComplexHandshake complex_hs;  
235 - SrsSimpleHandshake simple_hs;  
236 - if ((ret = simple_hs.handshake_with_server(skt, complex_hs)) != ERROR_SUCCESS) {  
237 - return ret;  
238 - }  
239 -  
240 - return ret;  
241 -}  
242 -  
243 -int SrsRtmpClient::connect_app(std::string app, std::string tc_url)  
244 -{  
245 - int ret = ERROR_SUCCESS;  
246 -  
247 - // Connect(vhost, app)  
248 - if (true) {  
249 - SrsCommonMessage* msg = new SrsCommonMessage();  
250 - SrsConnectAppPacket* pkt = new SrsConnectAppPacket();  
251 - msg->set_packet(pkt, 0);  
252 -  
253 - pkt->command_object = new SrsAmf0Object();  
254 - pkt->command_object->set("app", new SrsAmf0String(app.c_str()));  
255 - pkt->command_object->set("swfUrl", new SrsAmf0String());  
256 - pkt->command_object->set("tcUrl", new SrsAmf0String(tc_url.c_str()));  
257 - pkt->command_object->set("fpad", new SrsAmf0Boolean(false));  
258 - pkt->command_object->set("capabilities", new SrsAmf0Number(239));  
259 - pkt->command_object->set("audioCodecs", new SrsAmf0Number(3575));  
260 - pkt->command_object->set("videoCodecs", new SrsAmf0Number(252));  
261 - pkt->command_object->set("videoFunction", new SrsAmf0Number(1));  
262 - pkt->command_object->set("pageUrl", new SrsAmf0String());  
263 - pkt->command_object->set("objectEncoding", new SrsAmf0Number(0));  
264 -  
265 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
266 - return ret;  
267 - }  
268 - }  
269 -  
270 - // Set Window Acknowledgement size(2500000)  
271 - if (true) {  
272 - SrsCommonMessage* msg = new SrsCommonMessage();  
273 - SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();  
274 -  
275 - pkt->ackowledgement_window_size = 2500000;  
276 - msg->set_packet(pkt, 0);  
277 -  
278 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
279 - return ret;  
280 - }  
281 - }  
282 -  
283 - // expect connect _result  
284 - SrsCommonMessage* msg = NULL;  
285 - SrsConnectAppResPacket* pkt = NULL;  
286 - if ((ret = srs_rtmp_expect_message<SrsConnectAppResPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
287 - srs_error("expect connect app response message failed. ret=%d", ret);  
288 - return ret;  
289 - }  
290 - SrsAutoFree(SrsCommonMessage, msg, false);  
291 - srs_info("get connect app response message");  
292 -  
293 - return ret;  
294 -}  
295 -  
296 -int SrsRtmpClient::create_stream(int& stream_id)  
297 -{  
298 - int ret = ERROR_SUCCESS;  
299 -  
300 - // CreateStream  
301 - if (true) {  
302 - SrsCommonMessage* msg = new SrsCommonMessage();  
303 - SrsCreateStreamPacket* pkt = new SrsCreateStreamPacket();  
304 -  
305 - msg->set_packet(pkt, 0);  
306 -  
307 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
308 - return ret;  
309 - }  
310 - }  
311 -  
312 - // CreateStream _result.  
313 - if (true) {  
314 - SrsCommonMessage* msg = NULL;  
315 - SrsCreateStreamResPacket* pkt = NULL;  
316 - if ((ret = srs_rtmp_expect_message<SrsCreateStreamResPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
317 - srs_error("expect create stream response message failed. ret=%d", ret);  
318 - return ret;  
319 - }  
320 - SrsAutoFree(SrsCommonMessage, msg, false);  
321 - srs_info("get create stream response message");  
322 -  
323 - stream_id = (int)pkt->stream_id;  
324 - }  
325 -  
326 - return ret;  
327 -}  
328 -  
329 -int SrsRtmpClient::play(std::string stream, int stream_id)  
330 -{  
331 - int ret = ERROR_SUCCESS;  
332 -  
333 - // Play(stream)  
334 - if (true) {  
335 - SrsCommonMessage* msg = new SrsCommonMessage();  
336 - SrsPlayPacket* pkt = new SrsPlayPacket();  
337 -  
338 - pkt->stream_name = stream;  
339 - msg->set_packet(pkt, stream_id);  
340 -  
341 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
342 - srs_error("send play stream failed. "  
343 - "stream=%s, stream_id=%d, ret=%d",  
344 - stream.c_str(), stream_id, ret);  
345 - return ret;  
346 - }  
347 - }  
348 -  
349 - // SetBufferLength(1000ms)  
350 - int buffer_length_ms = 1000;  
351 - if (true) {  
352 - SrsCommonMessage* msg = new SrsCommonMessage();  
353 - SrsUserControlPacket* pkt = new SrsUserControlPacket();  
354 -  
355 - pkt->event_type = SrcPCUCSetBufferLength;  
356 - pkt->event_data = stream_id;  
357 - pkt->extra_data = buffer_length_ms;  
358 - msg->set_packet(pkt, 0);  
359 -  
360 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
361 - srs_error("send set buffer length failed. "  
362 - "stream=%s, stream_id=%d, bufferLength=%d, ret=%d",  
363 - stream.c_str(), stream_id, buffer_length_ms, ret);  
364 - return ret;  
365 - }  
366 - }  
367 -  
368 - return ret;  
369 -}  
370 -  
371 -int SrsRtmpClient::publish(std::string stream, int stream_id)  
372 -{  
373 - int ret = ERROR_SUCCESS;  
374 -  
375 - // publish(stream)  
376 - if (true) {  
377 - SrsCommonMessage* msg = new SrsCommonMessage();  
378 - SrsPublishPacket* pkt = new SrsPublishPacket();  
379 -  
380 - pkt->stream_name = stream;  
381 - msg->set_packet(pkt, stream_id);  
382 -  
383 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
384 - srs_error("send publish message failed. "  
385 - "stream=%s, stream_id=%d, ret=%d",  
386 - stream.c_str(), stream_id, ret);  
387 - return ret;  
388 - }  
389 - }  
390 -  
391 - return ret;  
392 -}  
393 -  
394 -SrsRtmp::SrsRtmp(st_netfd_t client_stfd)  
395 -{  
396 - protocol = new SrsProtocol(client_stfd);  
397 - stfd = client_stfd;  
398 -}  
399 -  
400 -SrsRtmp::~SrsRtmp()  
401 -{  
402 - srs_freep(protocol);  
403 -}  
404 -  
405 -SrsProtocol* SrsRtmp::get_protocol()  
406 -{  
407 - return protocol;  
408 -}  
409 -  
410 -void SrsRtmp::set_recv_timeout(int64_t timeout_us)  
411 -{  
412 - protocol->set_recv_timeout(timeout_us);  
413 -}  
414 -  
415 -int64_t SrsRtmp::get_recv_timeout()  
416 -{  
417 - return protocol->get_recv_timeout();  
418 -}  
419 -  
420 -void SrsRtmp::set_send_timeout(int64_t timeout_us)  
421 -{  
422 - protocol->set_send_timeout(timeout_us);  
423 -}  
424 -  
425 -int64_t SrsRtmp::get_recv_bytes()  
426 -{  
427 - return protocol->get_recv_bytes();  
428 -}  
429 -  
430 -int64_t SrsRtmp::get_send_bytes()  
431 -{  
432 - return protocol->get_send_bytes();  
433 -}  
434 -  
435 -int SrsRtmp::get_recv_kbps()  
436 -{  
437 - return protocol->get_recv_kbps();  
438 -}  
439 -  
440 -int SrsRtmp::get_send_kbps()  
441 -{  
442 - return protocol->get_send_kbps();  
443 -}  
444 -  
445 -int SrsRtmp::recv_message(SrsCommonMessage** pmsg)  
446 -{  
447 - return protocol->recv_message(pmsg);  
448 -}  
449 -  
450 -int SrsRtmp::send_message(ISrsMessage* msg)  
451 -{  
452 - return protocol->send_message(msg);  
453 -}  
454 -  
455 -int SrsRtmp::handshake()  
456 -{  
457 - int ret = ERROR_SUCCESS;  
458 -  
459 - SrsSocket skt(stfd);  
460 -  
461 - SrsComplexHandshake complex_hs;  
462 - SrsSimpleHandshake simple_hs;  
463 - if ((ret = simple_hs.handshake_with_client(skt, complex_hs)) != ERROR_SUCCESS) {  
464 - return ret;  
465 - }  
466 -  
467 - return ret;  
468 -}  
469 -  
470 -int SrsRtmp::connect_app(SrsRequest* req)  
471 -{  
472 - int ret = ERROR_SUCCESS;  
473 -  
474 - SrsCommonMessage* msg = NULL;  
475 - SrsConnectAppPacket* pkt = NULL;  
476 - if ((ret = srs_rtmp_expect_message<SrsConnectAppPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
477 - srs_error("expect connect app message failed. ret=%d", ret);  
478 - return ret;  
479 - }  
480 - SrsAutoFree(SrsCommonMessage, msg, false);  
481 - srs_info("get connect app message");  
482 -  
483 - SrsAmf0Any* prop = NULL;  
484 -  
485 - if ((prop = pkt->command_object->ensure_property_string("tcUrl")) == NULL) {  
486 - ret = ERROR_RTMP_REQ_CONNECT;  
487 - srs_error("invalid request, must specifies the tcUrl. ret=%d", ret);  
488 - return ret;  
489 - }  
490 - req->tcUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;  
491 -  
492 - if ((prop = pkt->command_object->ensure_property_string("pageUrl")) != NULL) {  
493 - req->pageUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;  
494 - }  
495 -  
496 - if ((prop = pkt->command_object->ensure_property_string("swfUrl")) != NULL) {  
497 - req->swfUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;  
498 - }  
499 -  
500 - if ((prop = pkt->command_object->ensure_property_number("objectEncoding")) != NULL) {  
501 - req->objectEncoding = srs_amf0_convert<SrsAmf0Number>(prop)->value;  
502 - }  
503 -  
504 - srs_info("get connect app message params success.");  
505 -  
506 - return req->discovery_app();  
507 -}  
508 -  
509 -int SrsRtmp::set_window_ack_size(int ack_size)  
510 -{  
511 - int ret = ERROR_SUCCESS;  
512 -  
513 - SrsCommonMessage* msg = new SrsCommonMessage();  
514 - SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();  
515 -  
516 - pkt->ackowledgement_window_size = ack_size;  
517 - msg->set_packet(pkt, 0);  
518 -  
519 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
520 - srs_error("send ack size message failed. ret=%d", ret);  
521 - return ret;  
522 - }  
523 - srs_info("send ack size message success. ack_size=%d", ack_size);  
524 -  
525 - return ret;  
526 -}  
527 -  
528 -int SrsRtmp::set_peer_bandwidth(int bandwidth, int type)  
529 -{  
530 - int ret = ERROR_SUCCESS;  
531 -  
532 - SrsCommonMessage* msg = new SrsCommonMessage();  
533 - SrsSetPeerBandwidthPacket* pkt = new SrsSetPeerBandwidthPacket();  
534 -  
535 - pkt->bandwidth = bandwidth;  
536 - pkt->type = type;  
537 - msg->set_packet(pkt, 0);  
538 -  
539 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
540 - srs_error("send set bandwidth message failed. ret=%d", ret);  
541 - return ret;  
542 - }  
543 - srs_info("send set bandwidth message "  
544 - "success. bandwidth=%d, type=%d", bandwidth, type);  
545 -  
546 - return ret;  
547 -}  
548 -  
549 -int SrsRtmp::response_connect_app(SrsRequest* req)  
550 -{  
551 - int ret = ERROR_SUCCESS;  
552 -  
553 - SrsCommonMessage* msg = new SrsCommonMessage();  
554 - SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket();  
555 -  
556 - pkt->props->set("fmsVer", new SrsAmf0String("FMS/"RTMP_SIG_FMS_VER));  
557 - pkt->props->set("capabilities", new SrsAmf0Number(127));  
558 - pkt->props->set("mode", new SrsAmf0Number(1));  
559 -  
560 - pkt->info->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
561 - pkt->info->set(StatusCode, new SrsAmf0String(StatusCodeConnectSuccess));  
562 - pkt->info->set(StatusDescription, new SrsAmf0String("Connection succeeded"));  
563 - pkt->info->set("objectEncoding", new SrsAmf0Number(req->objectEncoding));  
564 - SrsASrsAmf0EcmaArray* data = new SrsASrsAmf0EcmaArray();  
565 - pkt->info->set("data", data);  
566 -  
567 - data->set("srs_version", new SrsAmf0String(RTMP_SIG_FMS_VER));  
568 - data->set("srs_server", new SrsAmf0String(RTMP_SIG_SRS_NAME));  
569 - data->set("srs_license", new SrsAmf0String(RTMP_SIG_SRS_LICENSE));  
570 - data->set("srs_role", new SrsAmf0String(RTMP_SIG_SRS_ROLE));  
571 - data->set("srs_url", new SrsAmf0String(RTMP_SIG_SRS_URL));  
572 - data->set("srs_version", new SrsAmf0String(RTMP_SIG_SRS_VERSION));  
573 - data->set("srs_site", new SrsAmf0String(RTMP_SIG_SRS_WEB));  
574 - data->set("srs_email", new SrsAmf0String(RTMP_SIG_SRS_EMAIL));  
575 - data->set("srs_copyright", new SrsAmf0String(RTMP_SIG_SRS_COPYRIGHT));  
576 -  
577 - msg->set_packet(pkt, 0);  
578 -  
579 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
580 - srs_error("send connect app response message failed. ret=%d", ret);  
581 - return ret;  
582 - }  
583 - srs_info("send connect app response message success.");  
584 -  
585 - return ret;  
586 -}  
587 -  
588 -int SrsRtmp::on_bw_done()  
589 -{  
590 - int ret = ERROR_SUCCESS;  
591 -  
592 - SrsCommonMessage* msg = new SrsCommonMessage();  
593 - SrsOnBWDonePacket* pkt = new SrsOnBWDonePacket();  
594 -  
595 - msg->set_packet(pkt, 0);  
596 -  
597 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
598 - srs_error("send onBWDone message failed. ret=%d", ret);  
599 - return ret;  
600 - }  
601 - srs_info("send onBWDone message success.");  
602 -  
603 - return ret;  
604 -}  
605 -  
606 -int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& stream_name)  
607 -{  
608 - type = SrsClientUnknown;  
609 - int ret = ERROR_SUCCESS;  
610 -  
611 - while (true) {  
612 - SrsCommonMessage* msg = NULL;  
613 - if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {  
614 - srs_error("recv identify client message failed. ret=%d", ret);  
615 - return ret;  
616 - }  
617 -  
618 - SrsAutoFree(SrsCommonMessage, msg, false);  
619 -  
620 - if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {  
621 - srs_trace("identify ignore messages except "  
622 - "AMF0/AMF3 command message. type=%#x", msg->header.message_type);  
623 - continue;  
624 - }  
625 -  
626 - if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) {  
627 - srs_error("identify decode message failed. ret=%d", ret);  
628 - return ret;  
629 - }  
630 -  
631 - SrsPacket* pkt = msg->get_packet();  
632 - if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) {  
633 - srs_info("identify client by create stream, play or flash publish.");  
634 - return identify_create_stream_client(  
635 - dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name);  
636 - }  
637 - if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {  
638 - srs_info("identify client by releaseStream, fmle publish.");  
639 - return identify_fmle_publish_client(  
640 - dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name);  
641 - }  
642 -  
643 - srs_trace("ignore AMF0/AMF3 command message.");  
644 - }  
645 -  
646 - return ret;  
647 -}  
648 -  
649 -int SrsRtmp::set_chunk_size(int chunk_size)  
650 -{  
651 - int ret = ERROR_SUCCESS;  
652 -  
653 - SrsCommonMessage* msg = new SrsCommonMessage();  
654 - SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket();  
655 -  
656 - pkt->chunk_size = chunk_size;  
657 - msg->set_packet(pkt, 0);  
658 -  
659 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
660 - srs_error("send set chunk size message failed. ret=%d", ret);  
661 - return ret;  
662 - }  
663 - srs_info("send set chunk size message success. chunk_size=%d", chunk_size);  
664 -  
665 - return ret;  
666 -}  
667 -  
668 -int SrsRtmp::start_play(int stream_id)  
669 -{  
670 - int ret = ERROR_SUCCESS;  
671 -  
672 - // StreamBegin  
673 - if (true) {  
674 - SrsCommonMessage* msg = new SrsCommonMessage();  
675 - SrsUserControlPacket* pkt = new SrsUserControlPacket();  
676 -  
677 - pkt->event_type = SrcPCUCStreamBegin;  
678 - pkt->event_data = stream_id;  
679 - msg->set_packet(pkt, 0);  
680 -  
681 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
682 - srs_error("send PCUC(StreamBegin) message failed. ret=%d", ret);  
683 - return ret;  
684 - }  
685 - srs_info("send PCUC(StreamBegin) message success.");  
686 - }  
687 -  
688 - // onStatus(NetStream.Play.Reset)  
689 - if (true) {  
690 - SrsCommonMessage* msg = new SrsCommonMessage();  
691 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
692 -  
693 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
694 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamReset));  
695 - pkt->data->set(StatusDescription, new SrsAmf0String("Playing and resetting stream."));  
696 - pkt->data->set(StatusDetails, new SrsAmf0String("stream"));  
697 - pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));  
698 -  
699 - msg->set_packet(pkt, stream_id);  
700 -  
701 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
702 - srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret);  
703 - return ret;  
704 - }  
705 - srs_info("send onStatus(NetStream.Play.Reset) message success.");  
706 - }  
707 -  
708 - // onStatus(NetStream.Play.Start)  
709 - if (true) {  
710 - SrsCommonMessage* msg = new SrsCommonMessage();  
711 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
712 -  
713 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
714 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamStart));  
715 - pkt->data->set(StatusDescription, new SrsAmf0String("Started playing stream."));  
716 - pkt->data->set(StatusDetails, new SrsAmf0String("stream"));  
717 - pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));  
718 -  
719 - msg->set_packet(pkt, stream_id);  
720 -  
721 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
722 - srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret);  
723 - return ret;  
724 - }  
725 - srs_info("send onStatus(NetStream.Play.Reset) message success.");  
726 - }  
727 -  
728 - // |RtmpSampleAccess(false, false)  
729 - if (true) {  
730 - SrsCommonMessage* msg = new SrsCommonMessage();  
731 - SrsSampleAccessPacket* pkt = new SrsSampleAccessPacket();  
732 -  
733 - msg->set_packet(pkt, stream_id);  
734 -  
735 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
736 - srs_error("send |RtmpSampleAccess(false, false) message failed. ret=%d", ret);  
737 - return ret;  
738 - }  
739 - srs_info("send |RtmpSampleAccess(false, false) message success.");  
740 - }  
741 -  
742 - // onStatus(NetStream.Data.Start)  
743 - if (true) {  
744 - SrsCommonMessage* msg = new SrsCommonMessage();  
745 - SrsOnStatusDataPacket* pkt = new SrsOnStatusDataPacket();  
746 -  
747 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeDataStart));  
748 -  
749 - msg->set_packet(pkt, stream_id);  
750 -  
751 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
752 - srs_error("send onStatus(NetStream.Data.Start) message failed. ret=%d", ret);  
753 - return ret;  
754 - }  
755 - srs_info("send onStatus(NetStream.Data.Start) message success.");  
756 - }  
757 -  
758 - srs_info("start play success.");  
759 -  
760 - return ret;  
761 -}  
762 -  
763 -int SrsRtmp::on_play_client_pause(int stream_id, bool is_pause)  
764 -{  
765 - int ret = ERROR_SUCCESS;  
766 -  
767 - if (is_pause) {  
768 - // onStatus(NetStream.Pause.Notify)  
769 - if (true) {  
770 - SrsCommonMessage* msg = new SrsCommonMessage();  
771 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
772 -  
773 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
774 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamPause));  
775 - pkt->data->set(StatusDescription, new SrsAmf0String("Paused stream."));  
776 -  
777 - msg->set_packet(pkt, stream_id);  
778 -  
779 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
780 - srs_error("send onStatus(NetStream.Pause.Notify) message failed. ret=%d", ret);  
781 - return ret;  
782 - }  
783 - srs_info("send onStatus(NetStream.Pause.Notify) message success.");  
784 - }  
785 - // StreamEOF  
786 - if (true) {  
787 - SrsCommonMessage* msg = new SrsCommonMessage();  
788 - SrsUserControlPacket* pkt = new SrsUserControlPacket();  
789 -  
790 - pkt->event_type = SrcPCUCStreamEOF;  
791 - pkt->event_data = stream_id;  
792 - msg->set_packet(pkt, 0);  
793 -  
794 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
795 - srs_error("send PCUC(StreamEOF) message failed. ret=%d", ret);  
796 - return ret;  
797 - }  
798 - srs_info("send PCUC(StreamEOF) message success.");  
799 - }  
800 - } else {  
801 - // onStatus(NetStream.Unpause.Notify)  
802 - if (true) {  
803 - SrsCommonMessage* msg = new SrsCommonMessage();  
804 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
805 -  
806 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
807 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamUnpause));  
808 - pkt->data->set(StatusDescription, new SrsAmf0String("Unpaused stream."));  
809 -  
810 - msg->set_packet(pkt, stream_id);  
811 -  
812 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
813 - srs_error("send onStatus(NetStream.Unpause.Notify) message failed. ret=%d", ret);  
814 - return ret;  
815 - }  
816 - srs_info("send onStatus(NetStream.Unpause.Notify) message success.");  
817 - }  
818 - // StreanBegin  
819 - if (true) {  
820 - SrsCommonMessage* msg = new SrsCommonMessage();  
821 - SrsUserControlPacket* pkt = new SrsUserControlPacket();  
822 -  
823 - pkt->event_type = SrcPCUCStreamBegin;  
824 - pkt->event_data = stream_id;  
825 - msg->set_packet(pkt, 0);  
826 -  
827 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
828 - srs_error("send PCUC(StreanBegin) message failed. ret=%d", ret);  
829 - return ret;  
830 - }  
831 - srs_info("send PCUC(StreanBegin) message success.");  
832 - }  
833 - }  
834 -  
835 - return ret;  
836 -}  
837 -  
838 -int SrsRtmp::start_fmle_publish(int stream_id)  
839 -{  
840 - int ret = ERROR_SUCCESS;  
841 -  
842 - // FCPublish  
843 - double fc_publish_tid = 0;  
844 - if (true) {  
845 - SrsCommonMessage* msg = NULL;  
846 - SrsFMLEStartPacket* pkt = NULL;  
847 - if ((ret = srs_rtmp_expect_message<SrsFMLEStartPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
848 - srs_error("recv FCPublish message failed. ret=%d", ret);  
849 - return ret;  
850 - }  
851 - srs_info("recv FCPublish request message success.");  
852 -  
853 - SrsAutoFree(SrsCommonMessage, msg, false);  
854 - fc_publish_tid = pkt->transaction_id;  
855 - }  
856 - // FCPublish response  
857 - if (true) {  
858 - SrsCommonMessage* msg = new SrsCommonMessage();  
859 - SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(fc_publish_tid);  
860 -  
861 - msg->set_packet(pkt, 0);  
862 -  
863 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
864 - srs_error("send FCPublish response message failed. ret=%d", ret);  
865 - return ret;  
866 - }  
867 - srs_info("send FCPublish response message success.");  
868 - }  
869 -  
870 - // createStream  
871 - double create_stream_tid = 0;  
872 - if (true) {  
873 - SrsCommonMessage* msg = NULL;  
874 - SrsCreateStreamPacket* pkt = NULL;  
875 - if ((ret = srs_rtmp_expect_message<SrsCreateStreamPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
876 - srs_error("recv createStream message failed. ret=%d", ret);  
877 - return ret;  
878 - }  
879 - srs_info("recv createStream request message success.");  
880 -  
881 - SrsAutoFree(SrsCommonMessage, msg, false);  
882 - create_stream_tid = pkt->transaction_id;  
883 - }  
884 - // createStream response  
885 - if (true) {  
886 - SrsCommonMessage* msg = new SrsCommonMessage();  
887 - SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(create_stream_tid, stream_id);  
888 -  
889 - msg->set_packet(pkt, 0);  
890 -  
891 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
892 - srs_error("send createStream response message failed. ret=%d", ret);  
893 - return ret;  
894 - }  
895 - srs_info("send createStream response message success.");  
896 - }  
897 -  
898 - // publish  
899 - if (true) {  
900 - SrsCommonMessage* msg = NULL;  
901 - SrsPublishPacket* pkt = NULL;  
902 - if ((ret = srs_rtmp_expect_message<SrsPublishPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
903 - srs_error("recv publish message failed. ret=%d", ret);  
904 - return ret;  
905 - }  
906 - srs_info("recv publish request message success.");  
907 -  
908 - SrsAutoFree(SrsCommonMessage, msg, false);  
909 - }  
910 - // publish response onFCPublish(NetStream.Publish.Start)  
911 - if (true) {  
912 - SrsCommonMessage* msg = new SrsCommonMessage();  
913 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
914 -  
915 - pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_PUBLISH;  
916 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));  
917 - pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));  
918 -  
919 - msg->set_packet(pkt, stream_id);  
920 -  
921 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
922 - srs_error("send onFCPublish(NetStream.Publish.Start) message failed. ret=%d", ret);  
923 - return ret;  
924 - }  
925 - srs_info("send onFCPublish(NetStream.Publish.Start) message success.");  
926 - }  
927 - // publish response onStatus(NetStream.Publish.Start)  
928 - if (true) {  
929 - SrsCommonMessage* msg = new SrsCommonMessage();  
930 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
931 -  
932 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
933 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));  
934 - pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));  
935 - pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));  
936 -  
937 - msg->set_packet(pkt, stream_id);  
938 -  
939 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
940 - srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);  
941 - return ret;  
942 - }  
943 - srs_info("send onStatus(NetStream.Publish.Start) message success.");  
944 - }  
945 -  
946 - srs_info("FMLE publish success.");  
947 -  
948 - return ret;  
949 -}  
950 -  
951 -int SrsRtmp::fmle_unpublish(int stream_id, double unpublish_tid)  
952 -{  
953 - int ret = ERROR_SUCCESS;  
954 -  
955 - // publish response onFCUnpublish(NetStream.unpublish.Success)  
956 - if (true) {  
957 - SrsCommonMessage* msg = new SrsCommonMessage();  
958 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
959 -  
960 - pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH;  
961 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess));  
962 - pkt->data->set(StatusDescription, new SrsAmf0String("Stop publishing stream."));  
963 -  
964 - msg->set_packet(pkt, stream_id);  
965 -  
966 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
967 - srs_error("send onFCUnpublish(NetStream.unpublish.Success) message failed. ret=%d", ret);  
968 - return ret;  
969 - }  
970 - srs_info("send onFCUnpublish(NetStream.unpublish.Success) message success.");  
971 - }  
972 - // FCUnpublish response  
973 - if (true) {  
974 - SrsCommonMessage* msg = new SrsCommonMessage();  
975 - SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(unpublish_tid);  
976 -  
977 - msg->set_packet(pkt, stream_id);  
978 -  
979 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
980 - srs_error("send FCUnpublish response message failed. ret=%d", ret);  
981 - return ret;  
982 - }  
983 - srs_info("send FCUnpublish response message success.");  
984 - }  
985 - // publish response onStatus(NetStream.Unpublish.Success)  
986 - if (true) {  
987 - SrsCommonMessage* msg = new SrsCommonMessage();  
988 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
989 -  
990 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
991 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess));  
992 - pkt->data->set(StatusDescription, new SrsAmf0String("Stream is now unpublished"));  
993 - pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));  
994 -  
995 - msg->set_packet(pkt, stream_id);  
996 -  
997 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
998 - srs_error("send onStatus(NetStream.Unpublish.Success) message failed. ret=%d", ret);  
999 - return ret;  
1000 - }  
1001 - srs_info("send onStatus(NetStream.Unpublish.Success) message success.");  
1002 - }  
1003 -  
1004 - srs_info("FMLE unpublish success.");  
1005 -  
1006 - return ret;  
1007 -}  
1008 -  
1009 -int SrsRtmp::start_flash_publish(int stream_id)  
1010 -{  
1011 - int ret = ERROR_SUCCESS;  
1012 -  
1013 - // publish response onStatus(NetStream.Publish.Start)  
1014 - if (true) {  
1015 - SrsCommonMessage* msg = new SrsCommonMessage();  
1016 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
1017 -  
1018 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
1019 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));  
1020 - pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));  
1021 - pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));  
1022 -  
1023 - msg->set_packet(pkt, stream_id);  
1024 -  
1025 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
1026 - srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);  
1027 - return ret;  
1028 - }  
1029 - srs_info("send onStatus(NetStream.Publish.Start) message success.");  
1030 - }  
1031 -  
1032 - srs_info("flash publish success.");  
1033 -  
1034 - return ret;  
1035 -}  
1036 -  
1037 -int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name)  
1038 -{  
1039 - int ret = ERROR_SUCCESS;  
1040 -  
1041 - if (true) {  
1042 - SrsCommonMessage* msg = new SrsCommonMessage();  
1043 - SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id);  
1044 -  
1045 - msg->set_packet(pkt, 0);  
1046 -  
1047 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
1048 - srs_error("send createStream response message failed. ret=%d", ret);  
1049 - return ret;  
1050 - }  
1051 - srs_info("send createStream response message success.");  
1052 - }  
1053 -  
1054 - while (true) {  
1055 - SrsCommonMessage* msg = NULL;  
1056 - if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {  
1057 - srs_error("recv identify client message failed. ret=%d", ret);  
1058 - return ret;  
1059 - }  
1060 -  
1061 - SrsAutoFree(SrsCommonMessage, msg, false);  
1062 -  
1063 - if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {  
1064 - srs_trace("identify ignore messages except "  
1065 - "AMF0/AMF3 command message. type=%#x", msg->header.message_type);  
1066 - continue;  
1067 - }  
1068 -  
1069 - if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) {  
1070 - srs_error("identify decode message failed. ret=%d", ret);  
1071 - return ret;  
1072 - }  
1073 -  
1074 - SrsPacket* pkt = msg->get_packet();  
1075 - if (dynamic_cast<SrsPlayPacket*>(pkt)) {  
1076 - SrsPlayPacket* play = dynamic_cast<SrsPlayPacket*>(pkt);  
1077 - type = SrsClientPlay;  
1078 - stream_name = play->stream_name;  
1079 - srs_trace("identity client type=play, stream_name=%s", stream_name.c_str());  
1080 - return ret;  
1081 - }  
1082 - if (dynamic_cast<SrsPublishPacket*>(pkt)) {  
1083 - srs_info("identify client by publish, falsh publish.");  
1084 - return identify_flash_publish_client(  
1085 - dynamic_cast<SrsPublishPacket*>(pkt), type, stream_name);  
1086 - }  
1087 -  
1088 - srs_trace("ignore AMF0/AMF3 command message.");  
1089 - }  
1090 -  
1091 - return ret;  
1092 -}  
1093 -  
1094 -int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, std::string& stream_name)  
1095 -{  
1096 - int ret = ERROR_SUCCESS;  
1097 -  
1098 - type = SrsClientFMLEPublish;  
1099 - stream_name = req->stream_name;  
1100 -  
1101 - // releaseStream response  
1102 - if (true) {  
1103 - SrsCommonMessage* msg = new SrsCommonMessage();  
1104 - SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id);  
1105 -  
1106 - msg->set_packet(pkt, 0);  
1107 -  
1108 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
1109 - srs_error("send releaseStream response message failed. ret=%d", ret);  
1110 - return ret;  
1111 - }  
1112 - srs_info("send releaseStream response message success.");  
1113 - }  
1114 -  
1115 - return ret;  
1116 -}  
1117 -  
1118 -int SrsRtmp::identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& type, std::string& stream_name)  
1119 -{  
1120 - int ret = ERROR_SUCCESS;  
1121 -  
1122 - type = SrsClientFlashPublish;  
1123 - stream_name = req->stream_name;  
1124 -  
1125 - return ret;  
1126 -}  
1127 - 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_rtmp.hpp>
  25 +
  26 +#include <srs_core_log.hpp>
  27 +#include <srs_core_error.hpp>
  28 +#include <srs_core_socket.hpp>
  29 +#include <srs_core_protocol.hpp>
  30 +#include <srs_core_autofree.hpp>
  31 +#include <srs_core_amf0.hpp>
  32 +#include <srs_core_handshake.hpp>
  33 +#include <srs_core_config.hpp>
  34 +
  35 +/**
  36 +* the signature for packets to client.
  37 +*/
  38 +#define RTMP_SIG_FMS_VER "3,5,3,888"
  39 +#define RTMP_SIG_AMF0_VER 0
  40 +#define RTMP_SIG_CLIENT_ID "ASAICiss"
  41 +
  42 +/**
  43 +* onStatus consts.
  44 +*/
  45 +#define StatusLevel "level"
  46 +#define StatusCode "code"
  47 +#define StatusDescription "description"
  48 +#define StatusDetails "details"
  49 +#define StatusClientId "clientid"
  50 +// status value
  51 +#define StatusLevelStatus "status"
  52 +// code value
  53 +#define StatusCodeConnectSuccess "NetConnection.Connect.Success"
  54 +#define StatusCodeStreamReset "NetStream.Play.Reset"
  55 +#define StatusCodeStreamStart "NetStream.Play.Start"
  56 +#define StatusCodeStreamPause "NetStream.Pause.Notify"
  57 +#define StatusCodeStreamUnpause "NetStream.Unpause.Notify"
  58 +#define StatusCodePublishStart "NetStream.Publish.Start"
  59 +#define StatusCodeDataStart "NetStream.Data.Start"
  60 +#define StatusCodeUnpublishSuccess "NetStream.Unpublish.Success"
  61 +
  62 +// FMLE
  63 +#define RTMP_AMF0_COMMAND_ON_FC_PUBLISH "onFCPublish"
  64 +#define RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH "onFCUnpublish"
  65 +
  66 +// default stream id for response the createStream request.
  67 +#define SRS_DEFAULT_SID 1
  68 +
  69 +SrsRequest::SrsRequest()
  70 +{
  71 + objectEncoding = RTMP_SIG_AMF0_VER;
  72 +}
  73 +
  74 +SrsRequest::~SrsRequest()
  75 +{
  76 +}
  77 +
  78 +int SrsRequest::discovery_app()
  79 +{
  80 + int ret = ERROR_SUCCESS;
  81 +
  82 + size_t pos = std::string::npos;
  83 + std::string url = tcUrl;
  84 +
  85 + if ((pos = url.find("://")) != std::string::npos) {
  86 + schema = url.substr(0, pos);
  87 + url = url.substr(schema.length() + 3);
  88 + srs_verbose("discovery schema=%s", schema.c_str());
  89 + }
  90 +
  91 + if ((pos = url.find("/")) != std::string::npos) {
  92 + vhost = url.substr(0, pos);
  93 + url = url.substr(vhost.length() + 1);
  94 + srs_verbose("discovery vhost=%s", vhost.c_str());
  95 + }
  96 +
  97 + port = RTMP_DEFAULT_PORTS;
  98 + if ((pos = vhost.find(":")) != std::string::npos) {
  99 + port = vhost.substr(pos + 1);
  100 + vhost = vhost.substr(0, pos);
  101 + srs_verbose("discovery vhost=%s, port=%s", vhost.c_str(), port.c_str());
  102 + }
  103 +
  104 + app = url;
  105 + srs_vhost_resolve(vhost, app);
  106 +
  107 + // resolve the vhost from config
  108 + SrsConfDirective* parsed_vhost = config->get_vhost(vhost);
  109 + if (parsed_vhost) {
  110 + vhost = parsed_vhost->arg0();
  111 + }
  112 +
  113 + // TODO: discovery the params of vhost.
  114 +
  115 + srs_info("discovery app success. schema=%s, vhost=%s, port=%s, app=%s",
  116 + schema.c_str(), vhost.c_str(), port.c_str(), app.c_str());
  117 +
  118 + if (schema.empty() || vhost.empty() || port.empty() || app.empty()) {
  119 + ret = ERROR_RTMP_REQ_TCURL;
  120 + srs_error("discovery tcUrl failed. "
  121 + "tcUrl=%s, schema=%s, vhost=%s, port=%s, app=%s, ret=%d",
  122 + tcUrl.c_str(), schema.c_str(), vhost.c_str(), port.c_str(), app.c_str(), ret);
  123 + return ret;
  124 + }
  125 +
  126 + strip();
  127 +
  128 + return ret;
  129 +}
  130 +
  131 +std::string SrsRequest::get_stream_url()
  132 +{
  133 + std::string url = "";
  134 +
  135 + url += vhost;
  136 + url += "/";
  137 + url += app;
  138 + url += "/";
  139 + url += stream;
  140 +
  141 + return url;
  142 +}
  143 +
  144 +void SrsRequest::strip()
  145 +{
  146 + trim(vhost, "/ \n\r\t");
  147 + trim(app, "/ \n\r\t");
  148 + trim(stream, "/ \n\r\t");
  149 +}
  150 +
  151 +std::string& SrsRequest::trim(std::string& str, std::string chs)
  152 +{
  153 + for (int i = 0; i < (int)chs.length(); i++) {
  154 + char ch = chs.at(i);
  155 +
  156 + for (std::string::iterator it = str.begin(); it != str.end();) {
  157 + if (ch == *it) {
  158 + it = str.erase(it);
  159 + } else {
  160 + ++it;
  161 + }
  162 + }
  163 + }
  164 +
  165 + return str;
  166 +}
  167 +
  168 +SrsResponse::SrsResponse()
  169 +{
  170 + stream_id = SRS_DEFAULT_SID;
  171 +}
  172 +
  173 +SrsResponse::~SrsResponse()
  174 +{
  175 +}
  176 +
  177 +SrsRtmpClient::SrsRtmpClient(st_netfd_t _stfd)
  178 +{
  179 + stfd = _stfd;
  180 + protocol = new SrsProtocol(stfd);
  181 +}
  182 +
  183 +SrsRtmpClient::~SrsRtmpClient()
  184 +{
  185 + srs_freep(protocol);
  186 +}
  187 +
  188 +void SrsRtmpClient::set_recv_timeout(int64_t timeout_us)
  189 +{
  190 + protocol->set_recv_timeout(timeout_us);
  191 +}
  192 +
  193 +void SrsRtmpClient::set_send_timeout(int64_t timeout_us)
  194 +{
  195 + protocol->set_send_timeout(timeout_us);
  196 +}
  197 +
  198 +int64_t SrsRtmpClient::get_recv_bytes()
  199 +{
  200 + return protocol->get_recv_bytes();
  201 +}
  202 +
  203 +int64_t SrsRtmpClient::get_send_bytes()
  204 +{
  205 + return protocol->get_send_bytes();
  206 +}
  207 +
  208 +int SrsRtmpClient::get_recv_kbps()
  209 +{
  210 + return protocol->get_recv_kbps();
  211 +}
  212 +
  213 +int SrsRtmpClient::get_send_kbps()
  214 +{
  215 + return protocol->get_send_kbps();
  216 +}
  217 +
  218 +int SrsRtmpClient::recv_message(SrsCommonMessage** pmsg)
  219 +{
  220 + return protocol->recv_message(pmsg);
  221 +}
  222 +
  223 +int SrsRtmpClient::send_message(ISrsMessage* msg)
  224 +{
  225 + return protocol->send_message(msg);
  226 +}
  227 +
  228 +int SrsRtmpClient::handshake()
  229 +{
  230 + int ret = ERROR_SUCCESS;
  231 +
  232 + SrsSocket skt(stfd);
  233 +
  234 + SrsComplexHandshake complex_hs;
  235 + SrsSimpleHandshake simple_hs;
  236 + if ((ret = simple_hs.handshake_with_server(skt, complex_hs)) != ERROR_SUCCESS) {
  237 + return ret;
  238 + }
  239 +
  240 + return ret;
  241 +}
  242 +
  243 +int SrsRtmpClient::connect_app(std::string app, std::string tc_url)
  244 +{
  245 + int ret = ERROR_SUCCESS;
  246 +
  247 + // Connect(vhost, app)
  248 + if (true) {
  249 + SrsCommonMessage* msg = new SrsCommonMessage();
  250 + SrsConnectAppPacket* pkt = new SrsConnectAppPacket();
  251 + msg->set_packet(pkt, 0);
  252 +
  253 + pkt->command_object = new SrsAmf0Object();
  254 + pkt->command_object->set("app", new SrsAmf0String(app.c_str()));
  255 + pkt->command_object->set("swfUrl", new SrsAmf0String());
  256 + pkt->command_object->set("tcUrl", new SrsAmf0String(tc_url.c_str()));
  257 + pkt->command_object->set("fpad", new SrsAmf0Boolean(false));
  258 + pkt->command_object->set("capabilities", new SrsAmf0Number(239));
  259 + pkt->command_object->set("audioCodecs", new SrsAmf0Number(3575));
  260 + pkt->command_object->set("videoCodecs", new SrsAmf0Number(252));
  261 + pkt->command_object->set("videoFunction", new SrsAmf0Number(1));
  262 + pkt->command_object->set("pageUrl", new SrsAmf0String());
  263 + pkt->command_object->set("objectEncoding", new SrsAmf0Number(0));
  264 +
  265 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  266 + return ret;
  267 + }
  268 + }
  269 +
  270 + // Set Window Acknowledgement size(2500000)
  271 + if (true) {
  272 + SrsCommonMessage* msg = new SrsCommonMessage();
  273 + SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();
  274 +
  275 + pkt->ackowledgement_window_size = 2500000;
  276 + msg->set_packet(pkt, 0);
  277 +
  278 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  279 + return ret;
  280 + }
  281 + }
  282 +
  283 + // expect connect _result
  284 + SrsCommonMessage* msg = NULL;
  285 + SrsConnectAppResPacket* pkt = NULL;
  286 + if ((ret = srs_rtmp_expect_message<SrsConnectAppResPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  287 + srs_error("expect connect app response message failed. ret=%d", ret);
  288 + return ret;
  289 + }
  290 + SrsAutoFree(SrsCommonMessage, msg, false);
  291 + srs_info("get connect app response message");
  292 +
  293 + return ret;
  294 +}
  295 +
  296 +int SrsRtmpClient::create_stream(int& stream_id)
  297 +{
  298 + int ret = ERROR_SUCCESS;
  299 +
  300 + // CreateStream
  301 + if (true) {
  302 + SrsCommonMessage* msg = new SrsCommonMessage();
  303 + SrsCreateStreamPacket* pkt = new SrsCreateStreamPacket();
  304 +
  305 + msg->set_packet(pkt, 0);
  306 +
  307 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  308 + return ret;
  309 + }
  310 + }
  311 +
  312 + // CreateStream _result.
  313 + if (true) {
  314 + SrsCommonMessage* msg = NULL;
  315 + SrsCreateStreamResPacket* pkt = NULL;
  316 + if ((ret = srs_rtmp_expect_message<SrsCreateStreamResPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  317 + srs_error("expect create stream response message failed. ret=%d", ret);
  318 + return ret;
  319 + }
  320 + SrsAutoFree(SrsCommonMessage, msg, false);
  321 + srs_info("get create stream response message");
  322 +
  323 + stream_id = (int)pkt->stream_id;
  324 + }
  325 +
  326 + return ret;
  327 +}
  328 +
  329 +int SrsRtmpClient::play(std::string stream, int stream_id)
  330 +{
  331 + int ret = ERROR_SUCCESS;
  332 +
  333 + // Play(stream)
  334 + if (true) {
  335 + SrsCommonMessage* msg = new SrsCommonMessage();
  336 + SrsPlayPacket* pkt = new SrsPlayPacket();
  337 +
  338 + pkt->stream_name = stream;
  339 + msg->set_packet(pkt, stream_id);
  340 +
  341 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  342 + srs_error("send play stream failed. "
  343 + "stream=%s, stream_id=%d, ret=%d",
  344 + stream.c_str(), stream_id, ret);
  345 + return ret;
  346 + }
  347 + }
  348 +
  349 + // SetBufferLength(1000ms)
  350 + int buffer_length_ms = 1000;
  351 + if (true) {
  352 + SrsCommonMessage* msg = new SrsCommonMessage();
  353 + SrsUserControlPacket* pkt = new SrsUserControlPacket();
  354 +
  355 + pkt->event_type = SrcPCUCSetBufferLength;
  356 + pkt->event_data = stream_id;
  357 + pkt->extra_data = buffer_length_ms;
  358 + msg->set_packet(pkt, 0);
  359 +
  360 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  361 + srs_error("send set buffer length failed. "
  362 + "stream=%s, stream_id=%d, bufferLength=%d, ret=%d",
  363 + stream.c_str(), stream_id, buffer_length_ms, ret);
  364 + return ret;
  365 + }
  366 + }
  367 +
  368 + return ret;
  369 +}
  370 +
  371 +int SrsRtmpClient::publish(std::string stream, int stream_id)
  372 +{
  373 + int ret = ERROR_SUCCESS;
  374 +
  375 + // publish(stream)
  376 + if (true) {
  377 + SrsCommonMessage* msg = new SrsCommonMessage();
  378 + SrsPublishPacket* pkt = new SrsPublishPacket();
  379 +
  380 + pkt->stream_name = stream;
  381 + msg->set_packet(pkt, stream_id);
  382 +
  383 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  384 + srs_error("send publish message failed. "
  385 + "stream=%s, stream_id=%d, ret=%d",
  386 + stream.c_str(), stream_id, ret);
  387 + return ret;
  388 + }
  389 + }
  390 +
  391 + return ret;
  392 +}
  393 +
  394 +SrsRtmp::SrsRtmp(st_netfd_t client_stfd)
  395 +{
  396 + protocol = new SrsProtocol(client_stfd);
  397 + stfd = client_stfd;
  398 +}
  399 +
  400 +SrsRtmp::~SrsRtmp()
  401 +{
  402 + srs_freep(protocol);
  403 +}
  404 +
  405 +SrsProtocol* SrsRtmp::get_protocol()
  406 +{
  407 + return protocol;
  408 +}
  409 +
  410 +void SrsRtmp::set_recv_timeout(int64_t timeout_us)
  411 +{
  412 + protocol->set_recv_timeout(timeout_us);
  413 +}
  414 +
  415 +int64_t SrsRtmp::get_recv_timeout()
  416 +{
  417 + return protocol->get_recv_timeout();
  418 +}
  419 +
  420 +void SrsRtmp::set_send_timeout(int64_t timeout_us)
  421 +{
  422 + protocol->set_send_timeout(timeout_us);
  423 +}
  424 +
  425 +int64_t SrsRtmp::get_recv_bytes()
  426 +{
  427 + return protocol->get_recv_bytes();
  428 +}
  429 +
  430 +int64_t SrsRtmp::get_send_bytes()
  431 +{
  432 + return protocol->get_send_bytes();
  433 +}
  434 +
  435 +int SrsRtmp::get_recv_kbps()
  436 +{
  437 + return protocol->get_recv_kbps();
  438 +}
  439 +
  440 +int SrsRtmp::get_send_kbps()
  441 +{
  442 + return protocol->get_send_kbps();
  443 +}
  444 +
  445 +int SrsRtmp::recv_message(SrsCommonMessage** pmsg)
  446 +{
  447 + return protocol->recv_message(pmsg);
  448 +}
  449 +
  450 +int SrsRtmp::send_message(ISrsMessage* msg)
  451 +{
  452 + return protocol->send_message(msg);
  453 +}
  454 +
  455 +int SrsRtmp::handshake()
  456 +{
  457 + int ret = ERROR_SUCCESS;
  458 +
  459 + SrsSocket skt(stfd);
  460 +
  461 + SrsComplexHandshake complex_hs;
  462 + SrsSimpleHandshake simple_hs;
  463 + if ((ret = simple_hs.handshake_with_client(skt, complex_hs)) != ERROR_SUCCESS) {
  464 + return ret;
  465 + }
  466 +
  467 + return ret;
  468 +}
  469 +
  470 +int SrsRtmp::connect_app(SrsRequest* req)
  471 +{
  472 + int ret = ERROR_SUCCESS;
  473 +
  474 + SrsCommonMessage* msg = NULL;
  475 + SrsConnectAppPacket* pkt = NULL;
  476 + if ((ret = srs_rtmp_expect_message<SrsConnectAppPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  477 + srs_error("expect connect app message failed. ret=%d", ret);
  478 + return ret;
  479 + }
  480 + SrsAutoFree(SrsCommonMessage, msg, false);
  481 + srs_info("get connect app message");
  482 +
  483 + SrsAmf0Any* prop = NULL;
  484 +
  485 + if ((prop = pkt->command_object->ensure_property_string("tcUrl")) == NULL) {
  486 + ret = ERROR_RTMP_REQ_CONNECT;
  487 + srs_error("invalid request, must specifies the tcUrl. ret=%d", ret);
  488 + return ret;
  489 + }
  490 + req->tcUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;
  491 +
  492 + if ((prop = pkt->command_object->ensure_property_string("pageUrl")) != NULL) {
  493 + req->pageUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;
  494 + }
  495 +
  496 + if ((prop = pkt->command_object->ensure_property_string("swfUrl")) != NULL) {
  497 + req->swfUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;
  498 + }
  499 +
  500 + if ((prop = pkt->command_object->ensure_property_number("objectEncoding")) != NULL) {
  501 + req->objectEncoding = srs_amf0_convert<SrsAmf0Number>(prop)->value;
  502 + }
  503 +
  504 + srs_info("get connect app message params success.");
  505 +
  506 + return req->discovery_app();
  507 +}
  508 +
  509 +int SrsRtmp::set_window_ack_size(int ack_size)
  510 +{
  511 + int ret = ERROR_SUCCESS;
  512 +
  513 + SrsCommonMessage* msg = new SrsCommonMessage();
  514 + SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();
  515 +
  516 + pkt->ackowledgement_window_size = ack_size;
  517 + msg->set_packet(pkt, 0);
  518 +
  519 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  520 + srs_error("send ack size message failed. ret=%d", ret);
  521 + return ret;
  522 + }
  523 + srs_info("send ack size message success. ack_size=%d", ack_size);
  524 +
  525 + return ret;
  526 +}
  527 +
  528 +int SrsRtmp::set_peer_bandwidth(int bandwidth, int type)
  529 +{
  530 + int ret = ERROR_SUCCESS;
  531 +
  532 + SrsCommonMessage* msg = new SrsCommonMessage();
  533 + SrsSetPeerBandwidthPacket* pkt = new SrsSetPeerBandwidthPacket();
  534 +
  535 + pkt->bandwidth = bandwidth;
  536 + pkt->type = type;
  537 + msg->set_packet(pkt, 0);
  538 +
  539 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  540 + srs_error("send set bandwidth message failed. ret=%d", ret);
  541 + return ret;
  542 + }
  543 + srs_info("send set bandwidth message "
  544 + "success. bandwidth=%d, type=%d", bandwidth, type);
  545 +
  546 + return ret;
  547 +}
  548 +
  549 +int SrsRtmp::response_connect_app(SrsRequest* req)
  550 +{
  551 + int ret = ERROR_SUCCESS;
  552 +
  553 + SrsCommonMessage* msg = new SrsCommonMessage();
  554 + SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket();
  555 +
  556 + pkt->props->set("fmsVer", new SrsAmf0String("FMS/"RTMP_SIG_FMS_VER));
  557 + pkt->props->set("capabilities", new SrsAmf0Number(127));
  558 + pkt->props->set("mode", new SrsAmf0Number(1));
  559 +
  560 + pkt->info->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  561 + pkt->info->set(StatusCode, new SrsAmf0String(StatusCodeConnectSuccess));
  562 + pkt->info->set(StatusDescription, new SrsAmf0String("Connection succeeded"));
  563 + pkt->info->set("objectEncoding", new SrsAmf0Number(req->objectEncoding));
  564 + SrsASrsAmf0EcmaArray* data = new SrsASrsAmf0EcmaArray();
  565 + pkt->info->set("data", data);
  566 +
  567 + data->set("srs_version", new SrsAmf0String(RTMP_SIG_FMS_VER));
  568 + data->set("srs_server", new SrsAmf0String(RTMP_SIG_SRS_NAME));
  569 + data->set("srs_license", new SrsAmf0String(RTMP_SIG_SRS_LICENSE));
  570 + data->set("srs_role", new SrsAmf0String(RTMP_SIG_SRS_ROLE));
  571 + data->set("srs_url", new SrsAmf0String(RTMP_SIG_SRS_URL));
  572 + data->set("srs_version", new SrsAmf0String(RTMP_SIG_SRS_VERSION));
  573 + data->set("srs_site", new SrsAmf0String(RTMP_SIG_SRS_WEB));
  574 + data->set("srs_email", new SrsAmf0String(RTMP_SIG_SRS_EMAIL));
  575 + data->set("srs_copyright", new SrsAmf0String(RTMP_SIG_SRS_COPYRIGHT));
  576 +
  577 + msg->set_packet(pkt, 0);
  578 +
  579 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  580 + srs_error("send connect app response message failed. ret=%d", ret);
  581 + return ret;
  582 + }
  583 + srs_info("send connect app response message success.");
  584 +
  585 + return ret;
  586 +}
  587 +
  588 +int SrsRtmp::on_bw_done()
  589 +{
  590 + int ret = ERROR_SUCCESS;
  591 +
  592 + SrsCommonMessage* msg = new SrsCommonMessage();
  593 + SrsOnBWDonePacket* pkt = new SrsOnBWDonePacket();
  594 +
  595 + msg->set_packet(pkt, 0);
  596 +
  597 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  598 + srs_error("send onBWDone message failed. ret=%d", ret);
  599 + return ret;
  600 + }
  601 + srs_info("send onBWDone message success.");
  602 +
  603 + return ret;
  604 +}
  605 +
  606 +int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& stream_name)
  607 +{
  608 + type = SrsClientUnknown;
  609 + int ret = ERROR_SUCCESS;
  610 +
  611 + while (true) {
  612 + SrsCommonMessage* msg = NULL;
  613 + if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {
  614 + srs_error("recv identify client message failed. ret=%d", ret);
  615 + return ret;
  616 + }
  617 +
  618 + SrsAutoFree(SrsCommonMessage, msg, false);
  619 +
  620 + if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {
  621 + srs_trace("identify ignore messages except "
  622 + "AMF0/AMF3 command message. type=%#x", msg->header.message_type);
  623 + continue;
  624 + }
  625 +
  626 + if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) {
  627 + srs_error("identify decode message failed. ret=%d", ret);
  628 + return ret;
  629 + }
  630 +
  631 + SrsPacket* pkt = msg->get_packet();
  632 + if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) {
  633 + srs_info("identify client by create stream, play or flash publish.");
  634 + return identify_create_stream_client(
  635 + dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name);
  636 + }
  637 + if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
  638 + srs_info("identify client by releaseStream, fmle publish.");
  639 + return identify_fmle_publish_client(
  640 + dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name);
  641 + }
  642 +
  643 + srs_trace("ignore AMF0/AMF3 command message.");
  644 + }
  645 +
  646 + return ret;
  647 +}
  648 +
  649 +int SrsRtmp::set_chunk_size(int chunk_size)
  650 +{
  651 + int ret = ERROR_SUCCESS;
  652 +
  653 + SrsCommonMessage* msg = new SrsCommonMessage();
  654 + SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket();
  655 +
  656 + pkt->chunk_size = chunk_size;
  657 + msg->set_packet(pkt, 0);
  658 +
  659 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  660 + srs_error("send set chunk size message failed. ret=%d", ret);
  661 + return ret;
  662 + }
  663 + srs_info("send set chunk size message success. chunk_size=%d", chunk_size);
  664 +
  665 + return ret;
  666 +}
  667 +
  668 +int SrsRtmp::start_play(int stream_id)
  669 +{
  670 + int ret = ERROR_SUCCESS;
  671 +
  672 + // StreamBegin
  673 + if (true) {
  674 + SrsCommonMessage* msg = new SrsCommonMessage();
  675 + SrsUserControlPacket* pkt = new SrsUserControlPacket();
  676 +
  677 + pkt->event_type = SrcPCUCStreamBegin;
  678 + pkt->event_data = stream_id;
  679 + msg->set_packet(pkt, 0);
  680 +
  681 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  682 + srs_error("send PCUC(StreamBegin) message failed. ret=%d", ret);
  683 + return ret;
  684 + }
  685 + srs_info("send PCUC(StreamBegin) message success.");
  686 + }
  687 +
  688 + // onStatus(NetStream.Play.Reset)
  689 + if (true) {
  690 + SrsCommonMessage* msg = new SrsCommonMessage();
  691 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  692 +
  693 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  694 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamReset));
  695 + pkt->data->set(StatusDescription, new SrsAmf0String("Playing and resetting stream."));
  696 + pkt->data->set(StatusDetails, new SrsAmf0String("stream"));
  697 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  698 +
  699 + msg->set_packet(pkt, stream_id);
  700 +
  701 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  702 + srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret);
  703 + return ret;
  704 + }
  705 + srs_info("send onStatus(NetStream.Play.Reset) message success.");
  706 + }
  707 +
  708 + // onStatus(NetStream.Play.Start)
  709 + if (true) {
  710 + SrsCommonMessage* msg = new SrsCommonMessage();
  711 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  712 +
  713 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  714 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamStart));
  715 + pkt->data->set(StatusDescription, new SrsAmf0String("Started playing stream."));
  716 + pkt->data->set(StatusDetails, new SrsAmf0String("stream"));
  717 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  718 +
  719 + msg->set_packet(pkt, stream_id);
  720 +
  721 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  722 + srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret);
  723 + return ret;
  724 + }
  725 + srs_info("send onStatus(NetStream.Play.Reset) message success.");
  726 + }
  727 +
  728 + // |RtmpSampleAccess(false, false)
  729 + if (true) {
  730 + SrsCommonMessage* msg = new SrsCommonMessage();
  731 + SrsSampleAccessPacket* pkt = new SrsSampleAccessPacket();
  732 +
  733 + msg->set_packet(pkt, stream_id);
  734 +
  735 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  736 + srs_error("send |RtmpSampleAccess(false, false) message failed. ret=%d", ret);
  737 + return ret;
  738 + }
  739 + srs_info("send |RtmpSampleAccess(false, false) message success.");
  740 + }
  741 +
  742 + // onStatus(NetStream.Data.Start)
  743 + if (true) {
  744 + SrsCommonMessage* msg = new SrsCommonMessage();
  745 + SrsOnStatusDataPacket* pkt = new SrsOnStatusDataPacket();
  746 +
  747 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeDataStart));
  748 +
  749 + msg->set_packet(pkt, stream_id);
  750 +
  751 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  752 + srs_error("send onStatus(NetStream.Data.Start) message failed. ret=%d", ret);
  753 + return ret;
  754 + }
  755 + srs_info("send onStatus(NetStream.Data.Start) message success.");
  756 + }
  757 +
  758 + srs_info("start play success.");
  759 +
  760 + return ret;
  761 +}
  762 +
  763 +int SrsRtmp::on_play_client_pause(int stream_id, bool is_pause)
  764 +{
  765 + int ret = ERROR_SUCCESS;
  766 +
  767 + if (is_pause) {
  768 + // onStatus(NetStream.Pause.Notify)
  769 + if (true) {
  770 + SrsCommonMessage* msg = new SrsCommonMessage();
  771 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  772 +
  773 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  774 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamPause));
  775 + pkt->data->set(StatusDescription, new SrsAmf0String("Paused stream."));
  776 +
  777 + msg->set_packet(pkt, stream_id);
  778 +
  779 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  780 + srs_error("send onStatus(NetStream.Pause.Notify) message failed. ret=%d", ret);
  781 + return ret;
  782 + }
  783 + srs_info("send onStatus(NetStream.Pause.Notify) message success.");
  784 + }
  785 + // StreamEOF
  786 + if (true) {
  787 + SrsCommonMessage* msg = new SrsCommonMessage();
  788 + SrsUserControlPacket* pkt = new SrsUserControlPacket();
  789 +
  790 + pkt->event_type = SrcPCUCStreamEOF;
  791 + pkt->event_data = stream_id;
  792 + msg->set_packet(pkt, 0);
  793 +
  794 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  795 + srs_error("send PCUC(StreamEOF) message failed. ret=%d", ret);
  796 + return ret;
  797 + }
  798 + srs_info("send PCUC(StreamEOF) message success.");
  799 + }
  800 + } else {
  801 + // onStatus(NetStream.Unpause.Notify)
  802 + if (true) {
  803 + SrsCommonMessage* msg = new SrsCommonMessage();
  804 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  805 +
  806 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  807 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamUnpause));
  808 + pkt->data->set(StatusDescription, new SrsAmf0String("Unpaused stream."));
  809 +
  810 + msg->set_packet(pkt, stream_id);
  811 +
  812 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  813 + srs_error("send onStatus(NetStream.Unpause.Notify) message failed. ret=%d", ret);
  814 + return ret;
  815 + }
  816 + srs_info("send onStatus(NetStream.Unpause.Notify) message success.");
  817 + }
  818 + // StreanBegin
  819 + if (true) {
  820 + SrsCommonMessage* msg = new SrsCommonMessage();
  821 + SrsUserControlPacket* pkt = new SrsUserControlPacket();
  822 +
  823 + pkt->event_type = SrcPCUCStreamBegin;
  824 + pkt->event_data = stream_id;
  825 + msg->set_packet(pkt, 0);
  826 +
  827 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  828 + srs_error("send PCUC(StreanBegin) message failed. ret=%d", ret);
  829 + return ret;
  830 + }
  831 + srs_info("send PCUC(StreanBegin) message success.");
  832 + }
  833 + }
  834 +
  835 + return ret;
  836 +}
  837 +
  838 +int SrsRtmp::start_fmle_publish(int stream_id)
  839 +{
  840 + int ret = ERROR_SUCCESS;
  841 +
  842 + // FCPublish
  843 + double fc_publish_tid = 0;
  844 + if (true) {
  845 + SrsCommonMessage* msg = NULL;
  846 + SrsFMLEStartPacket* pkt = NULL;
  847 + if ((ret = srs_rtmp_expect_message<SrsFMLEStartPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  848 + srs_error("recv FCPublish message failed. ret=%d", ret);
  849 + return ret;
  850 + }
  851 + srs_info("recv FCPublish request message success.");
  852 +
  853 + SrsAutoFree(SrsCommonMessage, msg, false);
  854 + fc_publish_tid = pkt->transaction_id;
  855 + }
  856 + // FCPublish response
  857 + if (true) {
  858 + SrsCommonMessage* msg = new SrsCommonMessage();
  859 + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(fc_publish_tid);
  860 +
  861 + msg->set_packet(pkt, 0);
  862 +
  863 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  864 + srs_error("send FCPublish response message failed. ret=%d", ret);
  865 + return ret;
  866 + }
  867 + srs_info("send FCPublish response message success.");
  868 + }
  869 +
  870 + // createStream
  871 + double create_stream_tid = 0;
  872 + if (true) {
  873 + SrsCommonMessage* msg = NULL;
  874 + SrsCreateStreamPacket* pkt = NULL;
  875 + if ((ret = srs_rtmp_expect_message<SrsCreateStreamPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  876 + srs_error("recv createStream message failed. ret=%d", ret);
  877 + return ret;
  878 + }
  879 + srs_info("recv createStream request message success.");
  880 +
  881 + SrsAutoFree(SrsCommonMessage, msg, false);
  882 + create_stream_tid = pkt->transaction_id;
  883 + }
  884 + // createStream response
  885 + if (true) {
  886 + SrsCommonMessage* msg = new SrsCommonMessage();
  887 + SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(create_stream_tid, stream_id);
  888 +
  889 + msg->set_packet(pkt, 0);
  890 +
  891 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  892 + srs_error("send createStream response message failed. ret=%d", ret);
  893 + return ret;
  894 + }
  895 + srs_info("send createStream response message success.");
  896 + }
  897 +
  898 + // publish
  899 + if (true) {
  900 + SrsCommonMessage* msg = NULL;
  901 + SrsPublishPacket* pkt = NULL;
  902 + if ((ret = srs_rtmp_expect_message<SrsPublishPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  903 + srs_error("recv publish message failed. ret=%d", ret);
  904 + return ret;
  905 + }
  906 + srs_info("recv publish request message success.");
  907 +
  908 + SrsAutoFree(SrsCommonMessage, msg, false);
  909 + }
  910 + // publish response onFCPublish(NetStream.Publish.Start)
  911 + if (true) {
  912 + SrsCommonMessage* msg = new SrsCommonMessage();
  913 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  914 +
  915 + pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_PUBLISH;
  916 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));
  917 + pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));
  918 +
  919 + msg->set_packet(pkt, stream_id);
  920 +
  921 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  922 + srs_error("send onFCPublish(NetStream.Publish.Start) message failed. ret=%d", ret);
  923 + return ret;
  924 + }
  925 + srs_info("send onFCPublish(NetStream.Publish.Start) message success.");
  926 + }
  927 + // publish response onStatus(NetStream.Publish.Start)
  928 + if (true) {
  929 + SrsCommonMessage* msg = new SrsCommonMessage();
  930 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  931 +
  932 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  933 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));
  934 + pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));
  935 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  936 +
  937 + msg->set_packet(pkt, stream_id);
  938 +
  939 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  940 + srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);
  941 + return ret;
  942 + }
  943 + srs_info("send onStatus(NetStream.Publish.Start) message success.");
  944 + }
  945 +
  946 + srs_info("FMLE publish success.");
  947 +
  948 + return ret;
  949 +}
  950 +
  951 +int SrsRtmp::fmle_unpublish(int stream_id, double unpublish_tid)
  952 +{
  953 + int ret = ERROR_SUCCESS;
  954 +
  955 + // publish response onFCUnpublish(NetStream.unpublish.Success)
  956 + if (true) {
  957 + SrsCommonMessage* msg = new SrsCommonMessage();
  958 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  959 +
  960 + pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH;
  961 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess));
  962 + pkt->data->set(StatusDescription, new SrsAmf0String("Stop publishing stream."));
  963 +
  964 + msg->set_packet(pkt, stream_id);
  965 +
  966 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  967 + srs_error("send onFCUnpublish(NetStream.unpublish.Success) message failed. ret=%d", ret);
  968 + return ret;
  969 + }
  970 + srs_info("send onFCUnpublish(NetStream.unpublish.Success) message success.");
  971 + }
  972 + // FCUnpublish response
  973 + if (true) {
  974 + SrsCommonMessage* msg = new SrsCommonMessage();
  975 + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(unpublish_tid);
  976 +
  977 + msg->set_packet(pkt, stream_id);
  978 +
  979 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  980 + srs_error("send FCUnpublish response message failed. ret=%d", ret);
  981 + return ret;
  982 + }
  983 + srs_info("send FCUnpublish response message success.");
  984 + }
  985 + // publish response onStatus(NetStream.Unpublish.Success)
  986 + if (true) {
  987 + SrsCommonMessage* msg = new SrsCommonMessage();
  988 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  989 +
  990 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  991 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess));
  992 + pkt->data->set(StatusDescription, new SrsAmf0String("Stream is now unpublished"));
  993 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  994 +
  995 + msg->set_packet(pkt, stream_id);
  996 +
  997 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  998 + srs_error("send onStatus(NetStream.Unpublish.Success) message failed. ret=%d", ret);
  999 + return ret;
  1000 + }
  1001 + srs_info("send onStatus(NetStream.Unpublish.Success) message success.");
  1002 + }
  1003 +
  1004 + srs_info("FMLE unpublish success.");
  1005 +
  1006 + return ret;
  1007 +}
  1008 +
  1009 +int SrsRtmp::start_flash_publish(int stream_id)
  1010 +{
  1011 + int ret = ERROR_SUCCESS;
  1012 +
  1013 + // publish response onStatus(NetStream.Publish.Start)
  1014 + if (true) {
  1015 + SrsCommonMessage* msg = new SrsCommonMessage();
  1016 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  1017 +
  1018 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  1019 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));
  1020 + pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));
  1021 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  1022 +
  1023 + msg->set_packet(pkt, stream_id);
  1024 +
  1025 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  1026 + srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);
  1027 + return ret;
  1028 + }
  1029 + srs_info("send onStatus(NetStream.Publish.Start) message success.");
  1030 + }
  1031 +
  1032 + srs_info("flash publish success.");
  1033 +
  1034 + return ret;
  1035 +}
  1036 +
  1037 +int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name)
  1038 +{
  1039 + int ret = ERROR_SUCCESS;
  1040 +
  1041 + if (true) {
  1042 + SrsCommonMessage* msg = new SrsCommonMessage();
  1043 + SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id);
  1044 +
  1045 + msg->set_packet(pkt, 0);
  1046 +
  1047 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  1048 + srs_error("send createStream response message failed. ret=%d", ret);
  1049 + return ret;
  1050 + }
  1051 + srs_info("send createStream response message success.");
  1052 + }
  1053 +
  1054 + while (true) {
  1055 + SrsCommonMessage* msg = NULL;
  1056 + if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {
  1057 + srs_error("recv identify client message failed. ret=%d", ret);
  1058 + return ret;
  1059 + }
  1060 +
  1061 + SrsAutoFree(SrsCommonMessage, msg, false);
  1062 +
  1063 + if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {
  1064 + srs_trace("identify ignore messages except "
  1065 + "AMF0/AMF3 command message. type=%#x", msg->header.message_type);
  1066 + continue;
  1067 + }
  1068 +
  1069 + if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) {
  1070 + srs_error("identify decode message failed. ret=%d", ret);
  1071 + return ret;
  1072 + }
  1073 +
  1074 + SrsPacket* pkt = msg->get_packet();
  1075 + if (dynamic_cast<SrsPlayPacket*>(pkt)) {
  1076 + SrsPlayPacket* play = dynamic_cast<SrsPlayPacket*>(pkt);
  1077 + type = SrsClientPlay;
  1078 + stream_name = play->stream_name;
  1079 + srs_trace("identity client type=play, stream_name=%s", stream_name.c_str());
  1080 + return ret;
  1081 + }
  1082 + if (dynamic_cast<SrsPublishPacket*>(pkt)) {
  1083 + srs_info("identify client by publish, falsh publish.");
  1084 + return identify_flash_publish_client(
  1085 + dynamic_cast<SrsPublishPacket*>(pkt), type, stream_name);
  1086 + }
  1087 +
  1088 + srs_trace("ignore AMF0/AMF3 command message.");
  1089 + }
  1090 +
  1091 + return ret;
  1092 +}
  1093 +
  1094 +int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, std::string& stream_name)
  1095 +{
  1096 + int ret = ERROR_SUCCESS;
  1097 +
  1098 + type = SrsClientFMLEPublish;
  1099 + stream_name = req->stream_name;
  1100 +
  1101 + // releaseStream response
  1102 + if (true) {
  1103 + SrsCommonMessage* msg = new SrsCommonMessage();
  1104 + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id);
  1105 +
  1106 + msg->set_packet(pkt, 0);
  1107 +
  1108 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  1109 + srs_error("send releaseStream response message failed. ret=%d", ret);
  1110 + return ret;
  1111 + }
  1112 + srs_info("send releaseStream response message success.");
  1113 + }
  1114 +
  1115 + return ret;
  1116 +}
  1117 +
  1118 +int SrsRtmp::identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& type, std::string& stream_name)
  1119 +{
  1120 + int ret = ERROR_SUCCESS;
  1121 +
  1122 + type = SrsClientFlashPublish;
  1123 + stream_name = req->stream_name;
  1124 +
  1125 + return ret;
  1126 +}
  1127 +
@@ -32,8 +32,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -32,8 +32,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 32
33 #include <string> 33 #include <string>
34 34
35 -#include <st.h>  
36 -  
37 class SrsProtocol; 35 class SrsProtocol;
38 class ISrsMessage; 36 class ISrsMessage;
39 class SrsCommonMessage; 37 class SrsCommonMessage;
@@ -30,8 +30,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,8 +30,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 30
31 #include <algorithm> 31 #include <algorithm>
32 32
33 -#include <st.h>  
34 -  
35 #include <srs_core_log.hpp> 33 #include <srs_core_log.hpp>
36 #include <srs_core_error.hpp> 34 #include <srs_core_error.hpp>
37 #include <srs_core_client.hpp> 35 #include <srs_core_client.hpp>
@@ -48,24 +46,16 @@ SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type) @@ -48,24 +46,16 @@ SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type)
48 port = 0; 46 port = 0;
49 server = _server; 47 server = _server;
50 type = _type; 48 type = _type;
51 -  
52 - tid = NULL;  
53 - loop = false; 49 +
  50 + pthread = new SrsThread(this, 0);
54 } 51 }
55 52
56 SrsListener::~SrsListener() 53 SrsListener::~SrsListener()
57 { 54 {
58 - if (stfd) {  
59 - st_netfd_close(stfd);  
60 - stfd = NULL;  
61 - } 55 + srs_close_stfd(stfd);
62 56
63 - if (tid) {  
64 - loop = false;  
65 - st_thread_interrupt(tid);  
66 - st_thread_join(tid, NULL);  
67 - tid = NULL;  
68 - } 57 + pthread->stop();
  58 + srs_freep(pthread);
69 59
70 // st does not close it sometimes, 60 // st does not close it sometimes,
71 // close it manually. 61 // close it manually.
@@ -118,8 +108,7 @@ int SrsListener::listen(int _port) @@ -118,8 +108,7 @@ int SrsListener::listen(int _port)
118 } 108 }
119 srs_verbose("st open socket success. fd=%d", fd); 109 srs_verbose("st open socket success. fd=%d", fd);
120 110
121 - if ((tid = st_thread_create(listen_thread, this, 1, 0)) == NULL) {  
122 - ret = ERROR_ST_CREATE_LISTEN_THREAD; 111 + if ((ret = pthread->start()) != ERROR_SUCCESS) {
123 srs_error("st_thread_create listen thread error. ret=%d", ret); 112 srs_error("st_thread_create listen thread error. ret=%d", ret);
124 return ret; 113 return ret;
125 } 114 }
@@ -130,41 +119,32 @@ int SrsListener::listen(int _port) @@ -130,41 +119,32 @@ int SrsListener::listen(int _port)
130 return ret; 119 return ret;
131 } 120 }
132 121
133 -void SrsListener::listen_cycle() 122 +void SrsListener::on_enter_loop()
134 { 123 {
135 - int ret = ERROR_SUCCESS;  
136 -  
137 - log_context->generate_id();  
138 srs_trace("listen cycle start, port=%d, type=%d, fd=%d", port, type, fd); 124 srs_trace("listen cycle start, port=%d, type=%d, fd=%d", port, type, fd);
139 -  
140 - while (loop) {  
141 - st_netfd_t client_stfd = st_accept(stfd, NULL, NULL, ST_UTIME_NO_TIMEOUT);  
142 -  
143 - if(client_stfd == NULL){  
144 - // ignore error.  
145 - srs_warn("ignore accept thread stoppped for accept client error");  
146 - continue;  
147 - }  
148 - srs_verbose("get a client. fd=%d", st_netfd_fileno(client_stfd));  
149 -  
150 - if ((ret = server->accept_client(type, client_stfd)) != ERROR_SUCCESS) {  
151 - srs_warn("accept client error. ret=%d", ret);  
152 - continue;  
153 - }  
154 -  
155 - srs_verbose("accept client finished. conns=%d, ret=%d", (int)conns.size(), ret);  
156 - }  
157 } 125 }
158 126
159 -void* SrsListener::listen_thread(void* arg) 127 +int SrsListener::cycle()
160 { 128 {
161 - SrsListener* obj = (SrsListener*)arg;  
162 - srs_assert(obj != NULL); 129 + int ret = ERROR_SUCCESS;
163 130
164 - obj->loop = true;  
165 - obj->listen_cycle(); 131 + st_netfd_t client_stfd = st_accept(stfd, NULL, NULL, ST_UTIME_NO_TIMEOUT);
  132 +
  133 + if(client_stfd == NULL){
  134 + // ignore error.
  135 + srs_warn("ignore accept thread stoppped for accept client error");
  136 + return ret;
  137 + }
  138 + srs_verbose("get a client. fd=%d", st_netfd_fileno(client_stfd));
166 139
167 - return NULL; 140 + if ((ret = server->accept_client(type, client_stfd)) != ERROR_SUCCESS) {
  141 + srs_warn("accept client error. ret=%d", ret);
  142 + return ret;
  143 + }
  144 +
  145 + srs_verbose("accept client finished. conns=%d, ret=%d", (int)conns.size(), ret);
  146 +
  147 + return ret;
168 } 148 }
169 149
170 SrsServer::SrsServer() 150 SrsServer::SrsServer()
@@ -312,8 +292,7 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd) @@ -312,8 +292,7 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
312 srs_error("exceed the max connections, drop client: " 292 srs_error("exceed the max connections, drop client: "
313 "clients=%d, max=%d, fd=%d", (int)conns.size(), max_connections, fd); 293 "clients=%d, max=%d, fd=%d", (int)conns.size(), max_connections, fd);
314 294
315 - st_netfd_close(client_stfd);  
316 - ::close(fd); 295 + srs_close_stfd(client_stfd);
317 296
318 return ret; 297 return ret;
319 } 298 }
@@ -32,9 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -32,9 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 32
33 #include <vector> 33 #include <vector>
34 34
35 -#include <st.h>  
36 -  
37 #include <srs_core_reload.hpp> 35 #include <srs_core_reload.hpp>
  36 +#include <srs_core_thread.hpp>
38 37
39 class SrsServer; 38 class SrsServer;
40 class SrsConnection; 39 class SrsConnection;
@@ -45,7 +44,7 @@ enum SrsListenerType @@ -45,7 +44,7 @@ enum SrsListenerType
45 SrsListenerApi 44 SrsListenerApi
46 }; 45 };
47 46
48 -class SrsListener 47 +class SrsListener : public ISrsThreadHandler
49 { 48 {
50 public: 49 public:
51 SrsListenerType type; 50 SrsListenerType type;
@@ -54,16 +53,16 @@ private: @@ -54,16 +53,16 @@ private:
54 st_netfd_t stfd; 53 st_netfd_t stfd;
55 int port; 54 int port;
56 SrsServer* server; 55 SrsServer* server;
57 - st_thread_t tid;  
58 - bool loop; 56 + SrsThread* pthread;
59 public: 57 public:
60 SrsListener(SrsServer* _server, SrsListenerType _type); 58 SrsListener(SrsServer* _server, SrsListenerType _type);
61 virtual ~SrsListener(); 59 virtual ~SrsListener();
62 public: 60 public:
63 virtual int listen(int port); 61 virtual int listen(int port);
64 -private:  
65 - virtual void listen_cycle();  
66 - static void* listen_thread(void* arg); 62 +// interface ISrsThreadHandler.
  63 +public:
  64 + virtual void on_enter_loop();
  65 + virtual int cycle();
67 }; 66 };
68 67
69 class SrsServer : public SrsReloadHandler 68 class SrsServer : public SrsReloadHandler
@@ -30,8 +30,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,8 +30,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 30
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
33 -#include <st.h>  
34 -  
35 /** 33 /**
36 * the socket provides TCP socket over st, 34 * the socket provides TCP socket over st,
37 * that is, the sync socket mechanism. 35 * that is, the sync socket mechanism.