正在显示
6 个修改的文件
包含
291 行增加
和
1 行删除
| @@ -242,6 +242,7 @@ Supported operating systems and hardware: | @@ -242,6 +242,7 @@ Supported operating systems and hardware: | ||
| 242 | * 2013-10-17, Created.<br/> | 242 | * 2013-10-17, Created.<br/> |
| 243 | 243 | ||
| 244 | ## History | 244 | ## History |
| 245 | +* v1.0, 2014-06-28, response the call message with null. 0.9.137 | ||
| 245 | * v1.0, 2014-06-28, fix [#110](https://github.com/winlinvip/simple-rtmp-server/issues/110), thread start segment fault, thread cycle stop destroy thread. 0.9.136 | 246 | * v1.0, 2014-06-28, fix [#110](https://github.com/winlinvip/simple-rtmp-server/issues/110), thread start segment fault, thread cycle stop destroy thread. 0.9.136 |
| 246 | * v1.0, 2014-06-27, fix [#109](https://github.com/winlinvip/simple-rtmp-server/issues/109), fix the system jump time, adjust system startup time. 0.9.135 | 247 | * v1.0, 2014-06-27, fix [#109](https://github.com/winlinvip/simple-rtmp-server/issues/109), fix the system jump time, adjust system startup time. 0.9.135 |
| 247 | * <strong>v1.0, 2014-06-27, [1.0 mainline5(0.9.134)](https://github.com/winlinvip/simple-rtmp-server/releases/tag/1.0.mainline5) released. 41573 lines.</strong> | 248 | * <strong>v1.0, 2014-06-27, [1.0 mainline5(0.9.134)](https://github.com/winlinvip/simple-rtmp-server/releases/tag/1.0.mainline5) released. 41573 lines.</strong> |
| @@ -51,6 +51,7 @@ using namespace std; | @@ -51,6 +51,7 @@ using namespace std; | ||
| 51 | #include <srs_protocol_utility.hpp> | 51 | #include <srs_protocol_utility.hpp> |
| 52 | #include <srs_kernel_utility.hpp> | 52 | #include <srs_kernel_utility.hpp> |
| 53 | #include <srs_protocol_msg_array.hpp> | 53 | #include <srs_protocol_msg_array.hpp> |
| 54 | +#include <srs_protocol_amf0.hpp> | ||
| 54 | 55 | ||
| 55 | // when stream is busy, for example, streaming is already | 56 | // when stream is busy, for example, streaming is already |
| 56 | // publishing, when a new client to request to publish, | 57 | // publishing, when a new client to request to publish, |
| @@ -852,6 +853,22 @@ int SrsRtmpConn::process_play_control_msg(SrsConsumer* consumer, SrsMessage* msg | @@ -852,6 +853,22 @@ int SrsRtmpConn::process_play_control_msg(SrsConsumer* consumer, SrsMessage* msg | ||
| 852 | return ret; | 853 | return ret; |
| 853 | } | 854 | } |
| 854 | 855 | ||
| 856 | + // call msg, | ||
| 857 | + // support response null first, | ||
| 858 | + // @see https://github.com/winlinvip/simple-rtmp-server/issues/106 | ||
| 859 | + SrsCallPacket* call = dynamic_cast<SrsCallPacket*>(pkt); | ||
| 860 | + if (call) { | ||
| 861 | + SrsCallResPacket* res = new SrsCallResPacket(call->transaction_id); | ||
| 862 | + res->command_object = SrsAmf0Any::null(); | ||
| 863 | + res->response = SrsAmf0Any::null(); | ||
| 864 | + if ((ret = rtmp->send_and_free_packet(res, 0)) != ERROR_SUCCESS) { | ||
| 865 | + srs_warn("response call failed. ret=%d", ret); | ||
| 866 | + return ret; | ||
| 867 | + } | ||
| 868 | + return ret; | ||
| 869 | + } | ||
| 870 | + | ||
| 871 | + // pause or other msg. | ||
| 855 | SrsPausePacket* pause = dynamic_cast<SrsPausePacket*>(pkt); | 872 | SrsPausePacket* pause = dynamic_cast<SrsPausePacket*>(pkt); |
| 856 | if (!pause) { | 873 | if (!pause) { |
| 857 | srs_info("ignore all amf0/amf3 command except pause."); | 874 | srs_info("ignore all amf0/amf3 command except pause."); |
| @@ -926,6 +926,10 @@ int SrsSource::on_meta_data(SrsMessage* msg, SrsOnMetaDataPacket* metadata) | @@ -926,6 +926,10 @@ int SrsSource::on_meta_data(SrsMessage* msg, SrsOnMetaDataPacket* metadata) | ||
| 926 | metadata->metadata->set("server", SrsAmf0Any::str(RTMP_SIG_SRS_KEY" "RTMP_SIG_SRS_VERSION" ("RTMP_SIG_SRS_URL_SHORT")")); | 926 | metadata->metadata->set("server", SrsAmf0Any::str(RTMP_SIG_SRS_KEY" "RTMP_SIG_SRS_VERSION" ("RTMP_SIG_SRS_URL_SHORT")")); |
| 927 | metadata->metadata->set("authors", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY_AUTHROS)); | 927 | metadata->metadata->set("authors", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY_AUTHROS)); |
| 928 | 928 | ||
| 929 | + // version, for example, 1.0.0 | ||
| 930 | + // add version to metadata, please donot remove it, for debug. | ||
| 931 | + metadata->metadata->set("server_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); | ||
| 932 | + | ||
| 929 | if ((prop = metadata->metadata->get_property("audiosamplerate")) != NULL) { | 933 | if ((prop = metadata->metadata->get_property("audiosamplerate")) != NULL) { |
| 930 | if (prop->is_number()) { | 934 | if (prop->is_number()) { |
| 931 | sample_rate = (int)prop->to_number(); | 935 | sample_rate = (int)prop->to_number(); |
| @@ -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 "0" | 32 | #define VERSION_MAJOR "0" |
| 33 | #define VERSION_MINOR "9" | 33 | #define VERSION_MINOR "9" |
| 34 | -#define VERSION_REVISION "136" | 34 | +#define VERSION_REVISION "137" |
| 35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION | 35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION |
| 36 | // server info. | 36 | // server info. |
| 37 | #define RTMP_SIG_SRS_KEY "SRS" | 37 | #define RTMP_SIG_SRS_KEY "SRS" |
| @@ -700,6 +700,10 @@ int SrsProtocol::do_decode_message(SrsMessageHeader& header, SrsStream* stream, | @@ -700,6 +700,10 @@ int SrsProtocol::do_decode_message(SrsMessageHeader& header, SrsStream* stream, | ||
| 700 | srs_info("decode the AMF0/AMF3 closeStream message."); | 700 | srs_info("decode the AMF0/AMF3 closeStream message."); |
| 701 | *ppacket = packet = new SrsCloseStreamPacket(); | 701 | *ppacket = packet = new SrsCloseStreamPacket(); |
| 702 | return packet->decode(stream); | 702 | return packet->decode(stream); |
| 703 | + } else if (header.is_amf0_command() || header.is_amf3_command()) { | ||
| 704 | + srs_info("decode the AMF0/AMF3 call message."); | ||
| 705 | + *ppacket = packet = new SrsCallPacket(); | ||
| 706 | + return packet->decode(stream); | ||
| 703 | } | 707 | } |
| 704 | 708 | ||
| 705 | // default packet to drop message. | 709 | // default packet to drop message. |
| @@ -1976,6 +1980,202 @@ int SrsConnectAppResPacket::encode_packet(SrsStream* stream) | @@ -1976,6 +1980,202 @@ int SrsConnectAppResPacket::encode_packet(SrsStream* stream) | ||
| 1976 | return ret; | 1980 | return ret; |
| 1977 | } | 1981 | } |
| 1978 | 1982 | ||
| 1983 | +SrsCallPacket::SrsCallPacket() | ||
| 1984 | +{ | ||
| 1985 | + command_name = ""; | ||
| 1986 | + transaction_id = 0; | ||
| 1987 | + command_object = NULL; | ||
| 1988 | + arguments = NULL; | ||
| 1989 | +} | ||
| 1990 | + | ||
| 1991 | +SrsCallPacket::~SrsCallPacket() | ||
| 1992 | +{ | ||
| 1993 | + srs_freep(command_object); | ||
| 1994 | + srs_freep(arguments); | ||
| 1995 | +} | ||
| 1996 | + | ||
| 1997 | +int SrsCallPacket::decode(SrsStream* stream) | ||
| 1998 | +{ | ||
| 1999 | + int ret = ERROR_SUCCESS; | ||
| 2000 | + | ||
| 2001 | + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { | ||
| 2002 | + srs_error("amf0 decode call command_name failed. ret=%d", ret); | ||
| 2003 | + return ret; | ||
| 2004 | + } | ||
| 2005 | + if (command_name.empty()) { | ||
| 2006 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 2007 | + srs_error("amf0 decode call command_name failed. " | ||
| 2008 | + "command_name=%s, ret=%d", command_name.c_str(), ret); | ||
| 2009 | + return ret; | ||
| 2010 | + } | ||
| 2011 | + | ||
| 2012 | + if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) { | ||
| 2013 | + srs_error("amf0 decode call transaction_id failed. ret=%d", ret); | ||
| 2014 | + return ret; | ||
| 2015 | + } | ||
| 2016 | + | ||
| 2017 | + srs_freep(command_object); | ||
| 2018 | + if ((ret = SrsAmf0Any::discovery(stream, &command_object)) != ERROR_SUCCESS) { | ||
| 2019 | + srs_error("amf0 discovery call command_object failed. ret=%d", ret); | ||
| 2020 | + return ret; | ||
| 2021 | + } | ||
| 2022 | + if ((ret = command_object->read(stream)) != ERROR_SUCCESS) { | ||
| 2023 | + srs_error("amf0 decode call command_object failed. ret=%d", ret); | ||
| 2024 | + return ret; | ||
| 2025 | + } | ||
| 2026 | + | ||
| 2027 | + if (!stream->empty()) { | ||
| 2028 | + srs_freep(arguments); | ||
| 2029 | + if ((ret = SrsAmf0Any::discovery(stream, &arguments)) != ERROR_SUCCESS) { | ||
| 2030 | + srs_error("amf0 discovery call arguments failed. ret=%d", ret); | ||
| 2031 | + return ret; | ||
| 2032 | + } | ||
| 2033 | + if ((ret = arguments->read(stream)) != ERROR_SUCCESS) { | ||
| 2034 | + srs_error("amf0 decode call arguments failed. ret=%d", ret); | ||
| 2035 | + return ret; | ||
| 2036 | + } | ||
| 2037 | + } | ||
| 2038 | + | ||
| 2039 | + srs_info("amf0 decode call packet success"); | ||
| 2040 | + | ||
| 2041 | + return ret; | ||
| 2042 | +} | ||
| 2043 | + | ||
| 2044 | +int SrsCallPacket::get_perfer_cid() | ||
| 2045 | +{ | ||
| 2046 | + return RTMP_CID_OverConnection; | ||
| 2047 | +} | ||
| 2048 | + | ||
| 2049 | +int SrsCallPacket::get_message_type() | ||
| 2050 | +{ | ||
| 2051 | + return RTMP_MSG_AMF0CommandMessage; | ||
| 2052 | +} | ||
| 2053 | + | ||
| 2054 | +int SrsCallPacket::get_size() | ||
| 2055 | +{ | ||
| 2056 | + int size = 0; | ||
| 2057 | + | ||
| 2058 | + size += SrsAmf0Size::str(command_name) + SrsAmf0Size::number(); | ||
| 2059 | + | ||
| 2060 | + if (command_object) { | ||
| 2061 | + size += command_object->total_size(); | ||
| 2062 | + } | ||
| 2063 | + | ||
| 2064 | + if (arguments) { | ||
| 2065 | + size += arguments->total_size(); | ||
| 2066 | + } | ||
| 2067 | + | ||
| 2068 | + return size; | ||
| 2069 | +} | ||
| 2070 | + | ||
| 2071 | +int SrsCallPacket::encode_packet(SrsStream* stream) | ||
| 2072 | +{ | ||
| 2073 | + int ret = ERROR_SUCCESS; | ||
| 2074 | + | ||
| 2075 | + if ((ret = srs_amf0_write_string(stream, command_name)) != ERROR_SUCCESS) { | ||
| 2076 | + srs_error("encode command_name failed. ret=%d", ret); | ||
| 2077 | + return ret; | ||
| 2078 | + } | ||
| 2079 | + srs_verbose("encode command_name success."); | ||
| 2080 | + | ||
| 2081 | + if ((ret = srs_amf0_write_number(stream, transaction_id)) != ERROR_SUCCESS) { | ||
| 2082 | + srs_error("encode transaction_id failed. ret=%d", ret); | ||
| 2083 | + return ret; | ||
| 2084 | + } | ||
| 2085 | + srs_verbose("encode transaction_id success."); | ||
| 2086 | + | ||
| 2087 | + if (command_object && (ret = command_object->write(stream)) != ERROR_SUCCESS) { | ||
| 2088 | + srs_error("encode command_object failed. ret=%d", ret); | ||
| 2089 | + return ret; | ||
| 2090 | + } | ||
| 2091 | + srs_verbose("encode command_object success."); | ||
| 2092 | + | ||
| 2093 | + if (arguments && (ret = arguments->write(stream)) != ERROR_SUCCESS) { | ||
| 2094 | + srs_error("encode arguments failed. ret=%d", ret); | ||
| 2095 | + return ret; | ||
| 2096 | + } | ||
| 2097 | + srs_verbose("encode arguments success."); | ||
| 2098 | + | ||
| 2099 | + srs_info("encode create stream request packet success."); | ||
| 2100 | + | ||
| 2101 | + return ret; | ||
| 2102 | +} | ||
| 2103 | + | ||
| 2104 | +SrsCallResPacket::SrsCallResPacket(double _transaction_id) | ||
| 2105 | +{ | ||
| 2106 | + command_name = RTMP_AMF0_COMMAND_RESULT; | ||
| 2107 | + transaction_id = _transaction_id; | ||
| 2108 | + command_object = NULL; | ||
| 2109 | + response = NULL; | ||
| 2110 | +} | ||
| 2111 | + | ||
| 2112 | +SrsCallResPacket::~SrsCallResPacket() | ||
| 2113 | +{ | ||
| 2114 | + srs_freep(command_object); | ||
| 2115 | + srs_freep(response); | ||
| 2116 | +} | ||
| 2117 | + | ||
| 2118 | +int SrsCallResPacket::get_perfer_cid() | ||
| 2119 | +{ | ||
| 2120 | + return RTMP_CID_OverConnection; | ||
| 2121 | +} | ||
| 2122 | + | ||
| 2123 | +int SrsCallResPacket::get_message_type() | ||
| 2124 | +{ | ||
| 2125 | + return RTMP_MSG_AMF0CommandMessage; | ||
| 2126 | +} | ||
| 2127 | + | ||
| 2128 | +int SrsCallResPacket::get_size() | ||
| 2129 | +{ | ||
| 2130 | + int size = 0; | ||
| 2131 | + | ||
| 2132 | + size += SrsAmf0Size::str(command_name) + SrsAmf0Size::number(); | ||
| 2133 | + | ||
| 2134 | + if (command_object) { | ||
| 2135 | + size += command_object->total_size(); | ||
| 2136 | + } | ||
| 2137 | + | ||
| 2138 | + if (response) { | ||
| 2139 | + size += response->total_size(); | ||
| 2140 | + } | ||
| 2141 | + | ||
| 2142 | + return size; | ||
| 2143 | +} | ||
| 2144 | + | ||
| 2145 | +int SrsCallResPacket::encode_packet(SrsStream* stream) | ||
| 2146 | +{ | ||
| 2147 | + int ret = ERROR_SUCCESS; | ||
| 2148 | + | ||
| 2149 | + if ((ret = srs_amf0_write_string(stream, command_name)) != ERROR_SUCCESS) { | ||
| 2150 | + srs_error("encode command_name failed. ret=%d", ret); | ||
| 2151 | + return ret; | ||
| 2152 | + } | ||
| 2153 | + srs_verbose("encode command_name success."); | ||
| 2154 | + | ||
| 2155 | + if ((ret = srs_amf0_write_number(stream, transaction_id)) != ERROR_SUCCESS) { | ||
| 2156 | + srs_error("encode transaction_id failed. ret=%d", ret); | ||
| 2157 | + return ret; | ||
| 2158 | + } | ||
| 2159 | + srs_verbose("encode transaction_id success."); | ||
| 2160 | + | ||
| 2161 | + if (command_object && (ret = command_object->write(stream)) != ERROR_SUCCESS) { | ||
| 2162 | + srs_error("encode command_object failed. ret=%d", ret); | ||
| 2163 | + return ret; | ||
| 2164 | + } | ||
| 2165 | + srs_verbose("encode command_object success."); | ||
| 2166 | + | ||
| 2167 | + if (response && (ret = response->write(stream)) != ERROR_SUCCESS) { | ||
| 2168 | + srs_error("encode response failed. ret=%d", ret); | ||
| 2169 | + return ret; | ||
| 2170 | + } | ||
| 2171 | + srs_verbose("encode response success."); | ||
| 2172 | + | ||
| 2173 | + | ||
| 2174 | + srs_info("encode call response packet success."); | ||
| 2175 | + | ||
| 2176 | + return ret; | ||
| 2177 | +} | ||
| 2178 | + | ||
| 1979 | SrsCreateStreamPacket::SrsCreateStreamPacket() | 2179 | SrsCreateStreamPacket::SrsCreateStreamPacket() |
| 1980 | { | 2180 | { |
| 1981 | command_name = RTMP_AMF0_COMMAND_CREATE_STREAM; | 2181 | command_name = RTMP_AMF0_COMMAND_CREATE_STREAM; |
| @@ -534,6 +534,73 @@ protected: | @@ -534,6 +534,73 @@ protected: | ||
| 534 | }; | 534 | }; |
| 535 | 535 | ||
| 536 | /** | 536 | /** |
| 537 | +* 4.1.2. Call | ||
| 538 | +* The call method of the NetConnection object runs remote procedure | ||
| 539 | +* calls (RPC) at the receiving end. The called RPC name is passed as a | ||
| 540 | +* parameter to the call command. | ||
| 541 | +*/ | ||
| 542 | +class SrsCallPacket : public SrsPacket | ||
| 543 | +{ | ||
| 544 | +protected: | ||
| 545 | + virtual const char* get_class_name() | ||
| 546 | + { | ||
| 547 | + return CLASS_NAME_STRING(SrsCallPacket); | ||
| 548 | + } | ||
| 549 | +public: | ||
| 550 | + std::string command_name; | ||
| 551 | + double transaction_id; | ||
| 552 | + /** | ||
| 553 | + * If there exists any command info this | ||
| 554 | + * is set, else this is set to null type. | ||
| 555 | + */ | ||
| 556 | + SrsAmf0Any* command_object; | ||
| 557 | + // Any optional arguments to be provided | ||
| 558 | + SrsAmf0Any* arguments; | ||
| 559 | +public: | ||
| 560 | + SrsCallPacket(); | ||
| 561 | + virtual ~SrsCallPacket(); | ||
| 562 | +public: | ||
| 563 | + virtual int decode(SrsStream* stream); | ||
| 564 | +public: | ||
| 565 | + virtual int get_perfer_cid(); | ||
| 566 | +public: | ||
| 567 | + virtual int get_message_type(); | ||
| 568 | +protected: | ||
| 569 | + virtual int get_size(); | ||
| 570 | + virtual int encode_packet(SrsStream* stream); | ||
| 571 | +}; | ||
| 572 | +/** | ||
| 573 | +* response for SrsCallPacket. | ||
| 574 | +*/ | ||
| 575 | +class SrsCallResPacket : public SrsPacket | ||
| 576 | +{ | ||
| 577 | +protected: | ||
| 578 | + virtual const char* get_class_name() | ||
| 579 | + { | ||
| 580 | + return CLASS_NAME_STRING(SrsCallResPacket); | ||
| 581 | + } | ||
| 582 | +public: | ||
| 583 | + std::string command_name; | ||
| 584 | + double transaction_id; | ||
| 585 | + // If there exists any command info this | ||
| 586 | + // is set, else this is set to null type. | ||
| 587 | + SrsAmf0Any* command_object; | ||
| 588 | + // Response from the method that was | ||
| 589 | + // called. | ||
| 590 | + SrsAmf0Any* response; | ||
| 591 | +public: | ||
| 592 | + SrsCallResPacket(double _transaction_id); | ||
| 593 | + virtual ~SrsCallResPacket(); | ||
| 594 | +public: | ||
| 595 | + virtual int get_perfer_cid(); | ||
| 596 | +public: | ||
| 597 | + virtual int get_message_type(); | ||
| 598 | +protected: | ||
| 599 | + virtual int get_size(); | ||
| 600 | + virtual int encode_packet(SrsStream* stream); | ||
| 601 | +}; | ||
| 602 | + | ||
| 603 | +/** | ||
| 537 | * 4.1.3. createStream | 604 | * 4.1.3. createStream |
| 538 | * The client sends this command to the server to create a logical | 605 | * The client sends this command to the server to create a logical |
| 539 | * channel for message communication The publishing of audio, video, and | 606 | * channel for message communication The publishing of audio, video, and |
| @@ -592,6 +659,7 @@ protected: | @@ -592,6 +659,7 @@ protected: | ||
| 592 | virtual int get_size(); | 659 | virtual int get_size(); |
| 593 | virtual int encode_packet(SrsStream* stream); | 660 | virtual int encode_packet(SrsStream* stream); |
| 594 | }; | 661 | }; |
| 662 | + | ||
| 595 | /** | 663 | /** |
| 596 | * client close stream packet. | 664 | * client close stream packet. |
| 597 | */ | 665 | */ |
-
请 注册 或 登录 后发表评论