winlin

Fix #844, support Haivision encoder. 2.0.238

@@ -336,6 +336,7 @@ Remark: @@ -336,6 +336,7 @@ Remark:
336 336
337 ## History 337 ## History
338 338
  339 +* v2.0, 2017-04-15, Fix [#844][bug #844], support Haivision encoder. 2.0.238
339 * v2.0, 2017-04-15, Merge [#846][bug #846], fix fd leak for FLV stream caster. 2.0.237 340 * v2.0, 2017-04-15, Merge [#846][bug #846], fix fd leak for FLV stream caster. 2.0.237
340 * v2.0, 2017-04-15, Merge [#841][bug #841], avoid the duplicated sps/pps in ts. 2.0.236 341 * v2.0, 2017-04-15, Merge [#841][bug #841], avoid the duplicated sps/pps in ts. 2.0.236
341 * v2.0, 2017-04-09, Fix [#834][bug #834], crash for TS context corrupt. 2.0.235 342 * v2.0, 2017-04-09, Fix [#834][bug #834], crash for TS context corrupt. 2.0.235
@@ -1285,6 +1286,7 @@ Winlin @@ -1285,6 +1286,7 @@ Winlin
1285 [bug #834]: https://github.com/ossrs/srs/issues/834 1286 [bug #834]: https://github.com/ossrs/srs/issues/834
1286 [bug #841]: https://github.com/ossrs/srs/issues/841 1287 [bug #841]: https://github.com/ossrs/srs/issues/841
1287 [bug #846]: https://github.com/ossrs/srs/issues/846 1288 [bug #846]: https://github.com/ossrs/srs/issues/846
  1289 +[bug #844]: https://github.com/ossrs/srs/issues/844
1288 [bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx 1290 [bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx
1289 1291
1290 [exo #828]: https://github.com/google/ExoPlayer/pull/828 1292 [exo #828]: https://github.com/google/ExoPlayer/pull/828
@@ -546,6 +546,16 @@ int SrsRtmpConn::stream_service_cycle() @@ -546,6 +546,16 @@ int SrsRtmpConn::stream_service_cycle()
546 546
547 return publishing(source); 547 return publishing(source);
548 } 548 }
  549 + case SrsRtmpConnHaivisionPublish: {
  550 + srs_verbose("Haivision start to publish stream %s.", req->stream.c_str());
  551 +
  552 + if ((ret = rtmp->start_haivision_publish(res->stream_id)) != ERROR_SUCCESS) {
  553 + srs_error("start to publish stream failed. ret=%d", ret);
  554 + return ret;
  555 + }
  556 +
  557 + return publishing(source);
  558 + }
549 case SrsRtmpConnFlashPublish: { 559 case SrsRtmpConnFlashPublish: {
550 srs_verbose("flash start to publish stream %s.", req->stream.c_str()); 560 srs_verbose("flash start to publish stream %s.", req->stream.c_str());
551 561
@@ -839,7 +849,7 @@ int SrsRtmpConn::publishing(SrsSource* source) @@ -839,7 +849,7 @@ int SrsRtmpConn::publishing(SrsSource* source)
839 // @see: https://github.com/ossrs/srs/issues/237 849 // @see: https://github.com/ossrs/srs/issues/237
840 SrsPublishRecvThread trd(rtmp, req, 850 SrsPublishRecvThread trd(rtmp, req,
841 st_netfd_fileno(stfd), 0, this, source, 851 st_netfd_fileno(stfd), 0, this, source,
842 - client_type == SrsRtmpConnFMLEPublish, 852 + client_type != SrsRtmpConnFlashPublish,
843 vhost_is_edge); 853 vhost_is_edge);
844 854
845 srs_info("start to publish stream %s success", req->stream.c_str()); 855 srs_info("start to publish stream %s success", req->stream.c_str());
@@ -90,6 +90,7 @@ int SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std: @@ -90,6 +90,7 @@ int SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std:
90 break; 90 break;
91 case SrsRtmpConnFMLEPublish: 91 case SrsRtmpConnFMLEPublish:
92 case SrsRtmpConnFlashPublish: 92 case SrsRtmpConnFlashPublish:
  93 + case SrsRtmpConnHaivisionPublish:
93 if (rule->arg0() != "publish") { 94 if (rule->arg0() != "publish") {
94 break; 95 break;
95 } 96 }
@@ -135,6 +136,7 @@ int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std:: @@ -135,6 +136,7 @@ int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::
135 break; 136 break;
136 case SrsRtmpConnFMLEPublish: 137 case SrsRtmpConnFMLEPublish:
137 case SrsRtmpConnFlashPublish: 138 case SrsRtmpConnFlashPublish:
  139 + case SrsRtmpConnHaivisionPublish:
138 if (rule->arg0() != "publish") { 140 if (rule->arg0() != "publish") {
139 break; 141 break;
140 } 142 }
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 237 34 +#define VERSION_REVISION 238
35 35
36 // generated by configure, only macros. 36 // generated by configure, only macros.
37 #include <srs_auto_headers.hpp> 37 #include <srs_auto_headers.hpp>
@@ -1791,6 +1791,7 @@ string srs_client_type_string(SrsRtmpConnType type) @@ -1791,6 +1791,7 @@ string srs_client_type_string(SrsRtmpConnType type)
1791 case SrsRtmpConnPlay: return "Play"; 1791 case SrsRtmpConnPlay: return "Play";
1792 case SrsRtmpConnFlashPublish: return "flash-publish"; 1792 case SrsRtmpConnFlashPublish: return "flash-publish";
1793 case SrsRtmpConnFMLEPublish: return "fmle-publish"; 1793 case SrsRtmpConnFMLEPublish: return "fmle-publish";
  1794 + case SrsRtmpConnHaivisionPublish: return "haivision-publish";
1794 default: return "Unknown"; 1795 default: return "Unknown";
1795 } 1796 }
1796 } 1797 }
@@ -2693,6 +2694,14 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string& @@ -2693,6 +2694,14 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string&
2693 } 2694 }
2694 return ret; 2695 return ret;
2695 } 2696 }
  2697 +
  2698 + // For encoder of Haivision, it always send a _checkbw call message.
  2699 + // @Remark the next message is createStream, so we continue to identify it.
  2700 + // @see https://github.com/ossrs/srs/issues/844
  2701 + if (call->command_name == "_checkbw") {
  2702 + srs_info("Haivision encoder identified.");
  2703 + continue;
  2704 + }
2696 continue; 2705 continue;
2697 } 2706 }
2698 2707
@@ -2968,6 +2977,60 @@ int SrsRtmpServer::start_fmle_publish(int stream_id) @@ -2968,6 +2977,60 @@ int SrsRtmpServer::start_fmle_publish(int stream_id)
2968 return ret; 2977 return ret;
2969 } 2978 }
2970 2979
  2980 +int SrsRtmpServer::start_haivision_publish(int stream_id)
  2981 +{
  2982 + int ret = ERROR_SUCCESS;
  2983 +
  2984 + // publish
  2985 + if (true) {
  2986 + SrsCommonMessage* msg = NULL;
  2987 + SrsPublishPacket* pkt = NULL;
  2988 + if ((ret = expect_message<SrsPublishPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
  2989 + srs_error("recv publish message failed. ret=%d", ret);
  2990 + return ret;
  2991 + }
  2992 + srs_info("recv publish request message success.");
  2993 +
  2994 + SrsAutoFree(SrsCommonMessage, msg);
  2995 + SrsAutoFree(SrsPublishPacket, pkt);
  2996 + }
  2997 +
  2998 + // publish response onFCPublish(NetStream.Publish.Start)
  2999 + if (true) {
  3000 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  3001 +
  3002 + pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_PUBLISH;
  3003 + pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodePublishStart));
  3004 + pkt->data->set(StatusDescription, SrsAmf0Any::str("Started publishing stream."));
  3005 +
  3006 + if ((ret = protocol->send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
  3007 + srs_error("send onFCPublish(NetStream.Publish.Start) message failed. ret=%d", ret);
  3008 + return ret;
  3009 + }
  3010 + srs_info("send onFCPublish(NetStream.Publish.Start) message success.");
  3011 + }
  3012 +
  3013 + // publish response onStatus(NetStream.Publish.Start)
  3014 + if (true) {
  3015 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  3016 +
  3017 + pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelStatus));
  3018 + pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodePublishStart));
  3019 + pkt->data->set(StatusDescription, SrsAmf0Any::str("Started publishing stream."));
  3020 + pkt->data->set(StatusClientId, SrsAmf0Any::str(RTMP_SIG_CLIENT_ID));
  3021 +
  3022 + if ((ret = protocol->send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
  3023 + srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);
  3024 + return ret;
  3025 + }
  3026 + srs_info("send onStatus(NetStream.Publish.Start) message success.");
  3027 + }
  3028 +
  3029 + srs_info("Haivision publish success.");
  3030 +
  3031 + return ret;
  3032 +}
  3033 +
2971 int SrsRtmpServer::fmle_unpublish(int stream_id, double unpublish_tid) 3034 int SrsRtmpServer::fmle_unpublish(int stream_id, double unpublish_tid)
2972 { 3035 {
2973 int ret = ERROR_SUCCESS; 3036 int ret = ERROR_SUCCESS;
@@ -3102,6 +3165,10 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int @@ -3102,6 +3165,10 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int
3102 srs_info("identify client by create stream, play or flash publish."); 3165 srs_info("identify client by create stream, play or flash publish.");
3103 return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name, duration); 3166 return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name, duration);
3104 } 3167 }
  3168 + if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
  3169 + srs_info("identify client by FCPublish, haivision publish.");
  3170 + return identify_haivision_publish_client(dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name);
  3171 + }
3105 3172
3106 srs_trace("ignore AMF0/AMF3 command message."); 3173 srs_trace("ignore AMF0/AMF3 command message.");
3107 } 3174 }
@@ -3129,6 +3196,26 @@ int SrsRtmpServer::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmp @@ -3129,6 +3196,26 @@ int SrsRtmpServer::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmp
3129 return ret; 3196 return ret;
3130 } 3197 }
3131 3198
  3199 +int SrsRtmpServer::identify_haivision_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, string& stream_name)
  3200 +{
  3201 + int ret = ERROR_SUCCESS;
  3202 +
  3203 + type = SrsRtmpConnHaivisionPublish;
  3204 + stream_name = req->stream_name;
  3205 +
  3206 + // FCPublish response
  3207 + if (true) {
  3208 + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id);
  3209 + if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
  3210 + srs_error("send FCPublish response message failed. ret=%d", ret);
  3211 + return ret;
  3212 + }
  3213 + srs_info("send FCPublish response message success.");
  3214 + }
  3215 +
  3216 + return ret;
  3217 +}
  3218 +
3132 int SrsRtmpServer::identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, string& stream_name) 3219 int SrsRtmpServer::identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, string& stream_name)
3133 { 3220 {
3134 int ret = ERROR_SUCCESS; 3221 int ret = ERROR_SUCCESS;
@@ -69,6 +69,7 @@ class SrsCommonMessage; @@ -69,6 +69,7 @@ class SrsCommonMessage;
69 class SrsPacket; 69 class SrsPacket;
70 class SrsAmf0Object; 70 class SrsAmf0Object;
71 class IMergeReadHandler; 71 class IMergeReadHandler;
  72 +class SrsCallPacket;
72 73
73 /**************************************************************************** 74 /****************************************************************************
74 ***************************************************************************** 75 *****************************************************************************
@@ -631,6 +632,7 @@ enum SrsRtmpConnType @@ -631,6 +632,7 @@ enum SrsRtmpConnType
631 SrsRtmpConnPlay, 632 SrsRtmpConnPlay,
632 SrsRtmpConnFMLEPublish, 633 SrsRtmpConnFMLEPublish,
633 SrsRtmpConnFlashPublish, 634 SrsRtmpConnFlashPublish,
  635 + SrsRtmpConnHaivisionPublish,
634 }; 636 };
635 std::string srs_client_type_string(SrsRtmpConnType type); 637 std::string srs_client_type_string(SrsRtmpConnType type);
636 bool srs_client_type_is_publish(SrsRtmpConnType type); 638 bool srs_client_type_is_publish(SrsRtmpConnType type);
@@ -990,6 +992,11 @@ public: @@ -990,6 +992,11 @@ public:
990 */ 992 */
991 virtual int start_fmle_publish(int stream_id); 993 virtual int start_fmle_publish(int stream_id);
992 /** 994 /**
  995 + * For encoder of Haivision, response the startup request.
  996 + * @see https://github.com/ossrs/srs/issues/844
  997 + */
  998 + virtual int start_haivision_publish(int stream_id);
  999 + /**
993 * process the FMLE unpublish event. 1000 * process the FMLE unpublish event.
994 * @unpublish_tid the unpublish request transaction id. 1001 * @unpublish_tid the unpublish request transaction id.
995 */ 1002 */
@@ -1025,6 +1032,7 @@ public: @@ -1025,6 +1032,7 @@ public:
1025 private: 1032 private:
1026 virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, std::string& stream_name, double& duration); 1033 virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, std::string& stream_name, double& duration);
1027 virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name); 1034 virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name);
  1035 + virtual int identify_haivision_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name);
1028 virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, std::string& stream_name); 1036 virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, std::string& stream_name);
1029 private: 1037 private:
1030 virtual int identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, std::string& stream_name, double& duration); 1038 virtual int identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, std::string& stream_name, double& duration);
@@ -1293,7 +1301,7 @@ public: @@ -1293,7 +1301,7 @@ public:
1293 }; 1301 };
1294 1302
1295 /** 1303 /**
1296 -* FMLE start publish: ReleaseStream/PublishStream 1304 +* FMLE start publish: ReleaseStream/PublishStream/FCPublish/FCUnpublish
1297 */ 1305 */
1298 class SrsFMLEStartPacket : public SrsPacket 1306 class SrsFMLEStartPacket : public SrsPacket
1299 { 1307 {