winlin

support flash publish

@@ -26,9 +26,12 @@ Compare:<br/> @@ -26,9 +26,12 @@ Compare:<br/>
26 * nginx v1.5.0: 139524 lines <br/> 26 * nginx v1.5.0: 139524 lines <br/>
27 27
28 Features:<br/> 28 Features:<br/>
  29 +* v0.2, 2013-10-23, v0.2 released.
  30 +* v0.2, 2013-10-25, support flash publish.
29 * v0.2, 2013-10-25, support h264/avc codec by rtmp complex handshake(SrsComplexHandshake). 31 * v0.2, 2013-10-25, support h264/avc codec by rtmp complex handshake(SrsComplexHandshake).
30 * v0.2, 2013-10-24, support time jitter detect and correct algorithm(SrsConsumer::jitter_correct). 32 * v0.2, 2013-10-24, support time jitter detect and correct algorithm(SrsConsumer::jitter_correct).
31 -* v0.2, 2013-10-24, support decode the video/audio codec type(SrsCodec), cache the h264/avc sequence header. 33 +* v0.2, 2013-10-24, support decode codec type(SrsCodec) to cache the h264/avc sequence header.
  34 +* v0.1, 2013-10-23, v0.1 released.
32 * v0.1, 2013-10-23, support basic amf0 codec, simplify the api using c-style api. 35 * v0.1, 2013-10-23, support basic amf0 codec, simplify the api using c-style api.
33 * v0.1, 2013-10-23, support shared ptr msg(SrsSharedPtrMessage) for zero memory copy. 36 * v0.1, 2013-10-23, support shared ptr msg(SrsSharedPtrMessage) for zero memory copy.
34 * v0.1, 2013-10-22, support vp6 codec with rtmp protocol specified simple handshake. 37 * v0.1, 2013-10-22, support vp6 codec with rtmp protocol specified simple handshake.
@@ -137,15 +137,25 @@ int SrsClient::do_cycle() @@ -137,15 +137,25 @@ int SrsClient::do_cycle()
137 srs_info("start to play stream %s success", req->stream.c_str()); 137 srs_info("start to play stream %s success", req->stream.c_str());
138 return streaming_play(source); 138 return streaming_play(source);
139 } 139 }
140 - case SrsClientPublish: {  
141 - srs_verbose("start to publish stream %s.", req->stream.c_str()); 140 + case SrsClientFMLEPublish: {
  141 + srs_verbose("FMLE start to publish stream %s.", req->stream.c_str());
142 142
143 - if ((ret = rtmp->start_publish(res->stream_id)) != ERROR_SUCCESS) { 143 + if ((ret = rtmp->start_fmle_publish(res->stream_id)) != ERROR_SUCCESS) {
144 srs_error("start to publish stream failed. ret=%d", ret); 144 srs_error("start to publish stream failed. ret=%d", ret);
145 return ret; 145 return ret;
146 } 146 }
147 srs_info("start to publish stream %s success", req->stream.c_str()); 147 srs_info("start to publish stream %s success", req->stream.c_str());
148 - return streaming_publish(source); 148 + return streaming_publish(source, true);
  149 + }
  150 + case SrsClientFlashPublish: {
  151 + srs_verbose("flash start to publish stream %s.", req->stream.c_str());
  152 +
  153 + if ((ret = rtmp->start_flash_publish(res->stream_id)) != ERROR_SUCCESS) {
  154 + srs_error("flash start to publish stream failed. ret=%d", ret);
  155 + return ret;
  156 + }
  157 + srs_info("flash start to publish stream %s success", req->stream.c_str());
  158 + return streaming_publish(source, false);
149 } 159 }
150 default: { 160 default: {
151 ret = ERROR_SYSTEM_CLIENT_INVALID; 161 ret = ERROR_SYSTEM_CLIENT_INVALID;
@@ -237,7 +247,7 @@ int SrsClient::streaming_play(SrsSource* source) @@ -237,7 +247,7 @@ int SrsClient::streaming_play(SrsSource* source)
237 return ret; 247 return ret;
238 } 248 }
239 249
240 -int SrsClient::streaming_publish(SrsSource* source) 250 +int SrsClient::streaming_publish(SrsSource* source, bool is_fmle)
241 { 251 {
242 int ret = ERROR_SUCCESS; 252 int ret = ERROR_SUCCESS;
243 253
@@ -292,6 +302,12 @@ int SrsClient::streaming_publish(SrsSource* source) @@ -292,6 +302,12 @@ int SrsClient::streaming_publish(SrsSource* source)
292 srs_error("decode unpublish message failed. ret=%d", ret); 302 srs_error("decode unpublish message failed. ret=%d", ret);
293 return ret; 303 return ret;
294 } 304 }
  305 +
  306 + // flash unpublish.
  307 + if (!is_fmle) {
  308 + srs_trace("flash publish finished.");
  309 + return ret;
  310 + }
295 311
296 SrsPacket* pkt = msg->get_packet(); 312 SrsPacket* pkt = msg->get_packet();
297 if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) { 313 if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
@@ -54,7 +54,7 @@ protected: @@ -54,7 +54,7 @@ protected:
54 virtual int do_cycle(); 54 virtual int do_cycle();
55 private: 55 private:
56 virtual int streaming_play(SrsSource* source); 56 virtual int streaming_play(SrsSource* source);
57 - virtual int streaming_publish(SrsSource* source); 57 + virtual int streaming_publish(SrsSource* source, bool is_fmle);
58 virtual int get_peer_ip(); 58 virtual int get_peer_ip();
59 }; 59 };
60 60
@@ -1792,7 +1792,7 @@ int SrsPublishPacket::decode(SrsStream* stream) @@ -1792,7 +1792,7 @@ int SrsPublishPacket::decode(SrsStream* stream)
1792 return ret; 1792 return ret;
1793 } 1793 }
1794 1794
1795 - if ((ret = srs_amf0_read_string(stream, type)) != ERROR_SUCCESS) { 1795 + if (!stream->empty() && (ret = srs_amf0_read_string(stream, type)) != ERROR_SUCCESS) {
1796 srs_error("amf0 decode publish type failed. ret=%d", ret); 1796 srs_error("amf0 decode publish type failed. ret=%d", ret);
1797 return ret; 1797 return ret;
1798 } 1798 }
@@ -623,6 +623,7 @@ public: @@ -623,6 +623,7 @@ public:
623 double transaction_id; 623 double transaction_id;
624 SrsAmf0Null* command_object; 624 SrsAmf0Null* command_object;
625 std::string stream_name; 625 std::string stream_name;
  626 + // optional, default to live.
626 std::string type; 627 std::string type;
627 public: 628 public:
628 SrsPublishPacket(); 629 SrsPublishPacket();
@@ -395,7 +395,6 @@ int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& st @@ -395,7 +395,6 @@ int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& st
395 return identify_fmle_publish_client( 395 return identify_fmle_publish_client(
396 dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name); 396 dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name);
397 } 397 }
398 - // TODO: identify the flash publish client.  
399 398
400 srs_trace("ignore AMF0/AMF3 command message."); 399 srs_trace("ignore AMF0/AMF3 command message.");
401 } 400 }
@@ -517,7 +516,7 @@ int SrsRtmp::start_play(int stream_id) @@ -517,7 +516,7 @@ int SrsRtmp::start_play(int stream_id)
517 return ret; 516 return ret;
518 } 517 }
519 518
520 -int SrsRtmp::start_publish(int stream_id) 519 +int SrsRtmp::start_fmle_publish(int stream_id)
521 { 520 {
522 int ret = ERROR_SUCCESS; 521 int ret = ERROR_SUCCESS;
523 522
@@ -625,6 +624,8 @@ int SrsRtmp::start_publish(int stream_id) @@ -625,6 +624,8 @@ int SrsRtmp::start_publish(int stream_id)
625 srs_info("send onStatus(NetStream.Publish.Start) message success."); 624 srs_info("send onStatus(NetStream.Publish.Start) message success.");
626 } 625 }
627 626
  627 + srs_info("FMLE publish success.");
  628 +
628 return ret; 629 return ret;
629 } 630 }
630 631
@@ -686,6 +687,34 @@ int SrsRtmp::fmle_unpublish(int stream_id, double unpublish_tid) @@ -686,6 +687,34 @@ int SrsRtmp::fmle_unpublish(int stream_id, double unpublish_tid)
686 return ret; 687 return ret;
687 } 688 }
688 689
  690 +int SrsRtmp::start_flash_publish(int stream_id)
  691 +{
  692 + int ret = ERROR_SUCCESS;
  693 +
  694 + // publish response onStatus(NetStream.Publish.Start)
  695 + if (true) {
  696 + SrsCommonMessage* msg = new SrsCommonMessage();
  697 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  698 +
  699 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  700 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));
  701 + pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));
  702 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  703 +
  704 + msg->set_packet(pkt, stream_id);
  705 +
  706 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  707 + srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);
  708 + return ret;
  709 + }
  710 + srs_info("send onStatus(NetStream.Publish.Start) message success.");
  711 + }
  712 +
  713 + srs_info("flash publish success.");
  714 +
  715 + return ret;
  716 +}
  717 +
689 int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name) 718 int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name)
690 { 719 {
691 int ret = ERROR_SUCCESS; 720 int ret = ERROR_SUCCESS;
@@ -731,6 +760,11 @@ int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int strea @@ -731,6 +760,11 @@ int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int strea
731 srs_trace("identity client type=play, stream_name=%s", stream_name.c_str()); 760 srs_trace("identity client type=play, stream_name=%s", stream_name.c_str());
732 return ret; 761 return ret;
733 } 762 }
  763 + if (dynamic_cast<SrsPublishPacket*>(pkt)) {
  764 + srs_info("identify client by publish, falsh publish.");
  765 + return identify_flash_publish_client(
  766 + dynamic_cast<SrsPublishPacket*>(pkt), type, stream_name);
  767 + }
734 768
735 srs_trace("ignore AMF0/AMF3 command message."); 769 srs_trace("ignore AMF0/AMF3 command message.");
736 } 770 }
@@ -742,7 +776,7 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType @@ -742,7 +776,7 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType
742 { 776 {
743 int ret = ERROR_SUCCESS; 777 int ret = ERROR_SUCCESS;
744 778
745 - type = SrsClientPublish; 779 + type = SrsClientFMLEPublish;
746 stream_name = req->stream_name; 780 stream_name = req->stream_name;
747 781
748 // releaseStream response 782 // releaseStream response
@@ -762,3 +796,13 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType @@ -762,3 +796,13 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType
762 return ret; 796 return ret;
763 } 797 }
764 798
  799 +int SrsRtmp::identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& type, std::string& stream_name)
  800 +{
  801 + int ret = ERROR_SUCCESS;
  802 +
  803 + type = SrsClientFlashPublish;
  804 + stream_name = req->stream_name;
  805 +
  806 + return ret;
  807 +}
  808 +
@@ -40,6 +40,7 @@ class SrsCommonMessage; @@ -40,6 +40,7 @@ class SrsCommonMessage;
40 class SrsCreateStreamPacket; 40 class SrsCreateStreamPacket;
41 class SrsFMLEStartPacket; 41 class SrsFMLEStartPacket;
42 class SrsComplexHandshake; 42 class SrsComplexHandshake;
  43 +class SrsPublishPacket;
43 44
44 /** 45 /**
45 * the original request from client. 46 * the original request from client.
@@ -85,7 +86,8 @@ enum SrsClientType @@ -85,7 +86,8 @@ enum SrsClientType
85 { 86 {
86 SrsClientUnknown, 87 SrsClientUnknown,
87 SrsClientPlay, 88 SrsClientPlay,
88 - SrsClientPublish, 89 + SrsClientFMLEPublish,
  90 + SrsClientFlashPublish,
89 }; 91 };
90 92
91 /** 93 /**
@@ -146,15 +148,21 @@ public: @@ -146,15 +148,21 @@ public:
146 * onFCPublish(NetStream.Publish.Start) 148 * onFCPublish(NetStream.Publish.Start)
147 * onStatus(NetStream.Publish.Start) 149 * onStatus(NetStream.Publish.Start)
148 */ 150 */
149 - virtual int start_publish(int stream_id); 151 + virtual int start_fmle_publish(int stream_id);
150 /** 152 /**
151 * process the FMLE unpublish event. 153 * process the FMLE unpublish event.
152 * @unpublish_tid the unpublish request transaction id. 154 * @unpublish_tid the unpublish request transaction id.
153 */ 155 */
154 virtual int fmle_unpublish(int stream_id, double unpublish_tid); 156 virtual int fmle_unpublish(int stream_id, double unpublish_tid);
  157 + /**
  158 + * when client type is publish, response with packets:
  159 + * onStatus(NetStream.Publish.Start)
  160 + */
  161 + virtual int start_flash_publish(int stream_id);
155 private: 162 private:
156 virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name); 163 virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name);
157 virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, std::string& stream_name); 164 virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, std::string& stream_name);
  165 + virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& type, std::string& stream_name);
158 }; 166 };
159 167
160 #endif 168 #endif