正在显示
6 个修改的文件
包含
112 行增加
和
3 行删除
| @@ -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 | { |
-
请 注册 或 登录 后发表评论