From f0c24eeacc5a0a351bd2a660d887ba6729231bca Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2015 10:56:20 +0800 Subject: [PATCH 1/3] add stream caster for post flv over http. --- trunk/conf/full.conf | 7 +++ trunk/configure | 3 +- trunk/ide/srs_upp/srs_upp.upp | 2 + trunk/ide/srs_vs2010/srs.vcxproj | 4 +- .../srs_xcode.xcodeproj/project.pbxproj | 6 ++ trunk/src/app/srs_app_caster_flv.cpp | 48 ++++++++++++++ trunk/src/app/srs_app_caster_flv.hpp | 52 +++++++++++++++ trunk/src/app/srs_app_config.hpp | 1 + trunk/src/app/srs_app_server.cpp | 63 ++++++++++++++++++- trunk/src/app/srs_app_server.hpp | 20 ++++++ 10 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 trunk/src/app/srs_app_caster_flv.cpp create mode 100644 trunk/src/app/srs_app_caster_flv.hpp diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 78911b92f..a639e2675 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -159,6 +159,7 @@ stream_caster { # the caster type of stream, the casters: # mpegts_over_udp, MPEG-TS over UDP caster. # rtsp, Real Time Streaming Protocol (RTSP). + # flv, FLV over HTTP POST. caster mpegts_over_udp; # the output rtmp url. # for mpegts_over_udp caster, the typically output url: @@ -195,6 +196,12 @@ stream_caster { rtp_port_min 57200; rtp_port_max 57300; } +stream_caster { + enabled off; + caster flv; + output rtmp://127.0.0.1/[app]/[stream]; + listen 8936; +} ############################################################################################# # RTMP/HTTP VHOST sections diff --git a/trunk/configure b/trunk/configure index 067c91ca4..7f8727442 100755 --- a/trunk/configure +++ b/trunk/configure @@ -175,7 +175,8 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds" - "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call") + "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call" + "srs_app_caster_flv") DEFINES="" # add each modules for app for SRS_MODULE in ${SRS_MODULES[*]}; do diff --git a/trunk/ide/srs_upp/srs_upp.upp b/trunk/ide/srs_upp/srs_upp.upp index 424a3bbd3..e302bb98b 100755 --- a/trunk/ide/srs_upp/srs_upp.upp +++ b/trunk/ide/srs_upp/srs_upp.upp @@ -69,6 +69,8 @@ file ../../src/app/srs_app_async_call.cpp, ../../src/app/srs_app_bandwidth.hpp, ../../src/app/srs_app_bandwidth.cpp, + ../../src/app/srs_app_caster_flv.hpp, + ../../src/app/srs_app_caster_flv.cpp, ../../src/app/srs_app_conn.hpp, ../../src/app/srs_app_conn.cpp, ../../src/app/srs_app_config.hpp, diff --git a/trunk/ide/srs_vs2010/srs.vcxproj b/trunk/ide/srs_vs2010/srs.vcxproj index c9050517a..f7d0a9ff1 100755 --- a/trunk/ide/srs_vs2010/srs.vcxproj +++ b/trunk/ide/srs_vs2010/srs.vcxproj @@ -85,6 +85,7 @@ + @@ -165,6 +166,7 @@ + @@ -213,4 +215,4 @@ - \ No newline at end of file + diff --git a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj index 15522b837..94b678670 100644 --- a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj +++ b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj @@ -75,6 +75,7 @@ 3C1232ED1AAEA70F00CE8F6C /* libhttp_parser.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C1232EC1AAEA70F00CE8F6C /* libhttp_parser.a */; }; 3C1EE6AE1AB1055800576EE9 /* srs_app_hds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1EE6AC1AB1055800576EE9 /* srs_app_hds.cpp */; }; 3C1EE6D71AB1367D00576EE9 /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = 3C1EE6D61AB1367D00576EE9 /* README.md */; }; + 3C28EDDF1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C28EDDD1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp */; }; 3C36DB5B1ABD1CB90066CCAF /* srs_lib_bandwidth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB551ABD1CB90066CCAF /* srs_lib_bandwidth.cpp */; }; 3C36DB5C1ABD1CB90066CCAF /* srs_lib_simple_socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB571ABD1CB90066CCAF /* srs_lib_simple_socket.cpp */; }; 3C36DB5D1ABD1CB90066CCAF /* srs_librtmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB591ABD1CB90066CCAF /* srs_librtmp.cpp */; }; @@ -318,6 +319,8 @@ 3C1EE6D41AB1367D00576EE9 /* DONATIONS.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = DONATIONS.txt; path = ../../../DONATIONS.txt; sourceTree = ""; }; 3C1EE6D51AB1367D00576EE9 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../../../LICENSE; sourceTree = ""; }; 3C1EE6D61AB1367D00576EE9 /* README.md */ = {isa = PBXFileReference; explicitFileType = net.daringfireball.markdown; fileEncoding = 4; name = README.md; path = ../../../README.md; sourceTree = ""; wrapsLines = 0; }; + 3C28EDDD1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_caster_flv.cpp; path = ../../../src/app/srs_app_caster_flv.cpp; sourceTree = ""; }; + 3C28EDDE1AF5C43F00A3AEAC /* srs_app_caster_flv.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_caster_flv.hpp; path = ../../../src/app/srs_app_caster_flv.hpp; sourceTree = ""; }; 3C36DB551ABD1CB90066CCAF /* srs_lib_bandwidth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_lib_bandwidth.cpp; path = ../../../src/libs/srs_lib_bandwidth.cpp; sourceTree = ""; }; 3C36DB561ABD1CB90066CCAF /* srs_lib_bandwidth.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_lib_bandwidth.hpp; path = ../../../src/libs/srs_lib_bandwidth.hpp; sourceTree = ""; }; 3C36DB571ABD1CB90066CCAF /* srs_lib_simple_socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_lib_simple_socket.cpp; path = ../../../src/libs/srs_lib_simple_socket.cpp; sourceTree = ""; }; @@ -511,6 +514,8 @@ 3C12324B1AAE81CE00CE8F6C /* app */ = { isa = PBXGroup; children = ( + 3C28EDDD1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp */, + 3C28EDDE1AF5C43F00A3AEAC /* srs_app_caster_flv.hpp */, 3CD88B3D1ACA9C58000359E0 /* srs_app_async_call.cpp */, 3CD88B3E1ACA9C58000359E0 /* srs_app_async_call.hpp */, 3C12324C1AAE81D900CE8F6C /* srs_app_bandwidth.cpp */, @@ -908,6 +913,7 @@ 3C1232261AAE814D00CE8F6C /* srs_kernel_flv.cpp in Sources */, 3C663F1A1AB0155100286D8B /* srs_rtmp_dump.c in Sources */, 3CE6CD311AE4AFB800706E07 /* srs_main_ingest_hls.cpp in Sources */, + 3C28EDDF1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp in Sources */, 3C1232241AAE814D00CE8F6C /* srs_kernel_error.cpp in Sources */, 3C1232441AAE81A400CE8F6C /* srs_rtmp_handshake.cpp in Sources */, 3C1232291AAE814D00CE8F6C /* srs_kernel_stream.cpp in Sources */, diff --git a/trunk/src/app/srs_app_caster_flv.cpp b/trunk/src/app/srs_app_caster_flv.cpp new file mode 100644 index 000000000..11a4f1a03 --- /dev/null +++ b/trunk/src/app/srs_app_caster_flv.cpp @@ -0,0 +1,48 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2015 SRS(simple-rtmp-server) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include + +#ifdef SRS_AUTO_STREAM_CASTER + +#include +#include +#include +#include +#include + +SrsAppCasterFlv::SrsAppCasterFlv(SrsConfDirective* c) +{ +} + +SrsAppCasterFlv::~SrsAppCasterFlv() +{ +} + +int SrsAppCasterFlv::on_tcp_client(st_netfd_t stfd) +{ + int ret = ERROR_SUCCESS; + return ret; +} + +#endif diff --git a/trunk/src/app/srs_app_caster_flv.hpp b/trunk/src/app/srs_app_caster_flv.hpp new file mode 100644 index 000000000..6d0015e8c --- /dev/null +++ b/trunk/src/app/srs_app_caster_flv.hpp @@ -0,0 +1,52 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2015 SRS(simple-rtmp-server) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SRS_APP_CASTER_FLV_HPP +#define SRS_APP_CASTER_FLV_HPP + +/* +#include +*/ + +#include + +#ifdef SRS_AUTO_STREAM_CASTER + +class SrsConfDirective; + +#include +#include + +class SrsAppCasterFlv : public ISrsTcpHandler +{ +public: + SrsAppCasterFlv(SrsConfDirective* c); + virtual ~SrsAppCasterFlv(); +// ISrsTcpHandler +public: + virtual int on_tcp_client(st_netfd_t stfd); +}; + +#endif + +#endif diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index c32262cb2..6e2a1b353 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -100,6 +100,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SRS_CONF_DEFAULT_STREAM_CASTER_ENABLED false #define SRS_CONF_DEFAULT_STREAM_CASTER_MPEGTS_OVER_UDP "mpegts_over_udp" #define SRS_CONF_DEFAULT_STREAM_CASTER_RTSP "rtsp" +#define SRS_CONF_DEFAULT_STREAM_CASTER_FLV "flv" #define SRS_CONF_DEFAULT_STATS_NETWORK_DEVICE_INDEX 0 diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 3c21a542b..b522c2545 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -46,6 +46,7 @@ using namespace std; #include #include #include +#include // signal defines. #define SIGNAL_RELOAD SIGHUP @@ -206,7 +207,7 @@ int SrsRtspListener::listen(string ip, int port) listener = new SrsTcpListener(this, ip, port); if ((ret = listener->listen()) != ERROR_SUCCESS) { - srs_error("udp caster listen failed. ret=%d", ret); + srs_error("rtsp caster listen failed. ret=%d", ret); return ret; } @@ -231,6 +232,64 @@ int SrsRtspListener::on_tcp_client(st_netfd_t stfd) return ret; } +SrsHttpFlvListener::SrsHttpFlvListener(SrsServer* server, SrsListenerType type, SrsConfDirective* c) : SrsListener(server, type) +{ + listener = NULL; + + // the caller already ensure the type is ok, + // we just assert here for unknown stream caster. + srs_assert(_type == SrsListenerRtsp); + if (_type == SrsListenerRtsp) { + caster = new SrsAppCasterFlv(c); + } +} + +SrsHttpFlvListener::~SrsHttpFlvListener() +{ + srs_freep(caster); + srs_freep(listener); +} + +int SrsHttpFlvListener::listen(string ip, int port) +{ + int ret = ERROR_SUCCESS; + + // the caller already ensure the type is ok, + // we just assert here for unknown stream caster. + srs_assert(_type == SrsListenerRtsp); + + _ip = ip; + _port = port; + + srs_freep(listener); + listener = new SrsTcpListener(this, ip, port); + + if ((ret = listener->listen()) != ERROR_SUCCESS) { + srs_error("flv caster listen failed. ret=%d", ret); + return ret; + } + + srs_info("listen thread cid=%d, current_cid=%d, " + "listen at port=%d, type=%d, fd=%d started success, ep=%s:%d", + pthread->cid(), _srs_context->get_id(), _port, _type, fd, ip.c_str(), port); + + srs_trace("%s listen at tcp://%s:%d, fd=%d", srs_listener_type2string(_type).c_str(), ip.c_str(), _port, listener->fd()); + + return ret; +} + +int SrsHttpFlvListener::on_tcp_client(st_netfd_t stfd) +{ + int ret = ERROR_SUCCESS; + + if ((ret = caster->on_tcp_client(stfd)) != ERROR_SUCCESS) { + srs_warn("accept client error. ret=%d", ret); + return ret; + } + + return ret; +} + SrsUdpCasterListener::SrsUdpCasterListener(SrsServer* server, SrsListenerType type, SrsConfDirective* c) : SrsListener(server, type) { _type = type; @@ -1003,6 +1062,8 @@ int SrsServer::listen_stream_caster() listener = new SrsUdpCasterListener(this, SrsListenerMpegTsOverUdp, stream_caster); } else if (caster == SRS_CONF_DEFAULT_STREAM_CASTER_RTSP) { listener = new SrsRtspListener(this, SrsListenerRtsp, stream_caster); + } else if (caster == SRS_CONF_DEFAULT_STREAM_CASTER_FLV) { + listener = new SrsHttpFlvListener(this, SrsListenerFlv, stream_caster); } else { ret = ERROR_STREAM_CASTER_ENGINE; srs_error("unsupported stream caster %s. ret=%d", caster.c_str(), ret); diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index 1bad2d8b1..b2ecafbb1 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -66,6 +66,8 @@ enum SrsListenerType SrsListenerMpegTsOverUdp = 3, // TCP stream, RTSP stream. SrsListenerRtsp = 4, + // HTTP stream, FLV over HTTP POST. + SrsListenerFlv = 5, }; /** @@ -123,6 +125,24 @@ public: virtual int on_tcp_client(st_netfd_t stfd); }; +/** + * the tcp listener, for http flv server. + */ +class SrsHttpFlvListener : virtual public SrsListener, virtual public ISrsTcpHandler +{ +private: + SrsTcpListener* listener; + ISrsTcpHandler* caster; +public: + SrsHttpFlvListener(SrsServer* server, SrsListenerType type, SrsConfDirective* c); + virtual ~SrsHttpFlvListener(); +public: + virtual int listen(std::string ip, int port); +// ISrsTcpHandler +public: + virtual int on_tcp_client(st_netfd_t stfd); +}; + /** * the udp listener, for udp server. */ From 022b6aa56185f15069b460c6cc81ec999d7f29e3 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2015 23:34:59 +0800 Subject: [PATCH 2/3] refine the http remux for http flv stream. --- trunk/src/app/srs_app_caster_flv.cpp | 43 ++++++++++++++++++++++++++++ trunk/src/app/srs_app_caster_flv.hpp | 22 +++++++++++++- trunk/src/app/srs_app_conn.cpp | 17 +++++++---- trunk/src/app/srs_app_conn.hpp | 23 ++++++++++++--- trunk/src/app/srs_app_http_api.cpp | 4 +-- trunk/src/app/srs_app_http_api.hpp | 2 +- trunk/src/app/srs_app_http_conn.cpp | 8 +++--- trunk/src/app/srs_app_http_conn.hpp | 5 ++-- trunk/src/app/srs_app_rtmp_conn.cpp | 7 +++-- trunk/src/app/srs_app_rtmp_conn.hpp | 4 ++- trunk/src/app/srs_app_server.cpp | 14 ++++++--- trunk/src/app/srs_app_server.hpp | 15 +++++++--- 12 files changed, 133 insertions(+), 31 deletions(-) diff --git a/trunk/src/app/srs_app_caster_flv.cpp b/trunk/src/app/srs_app_caster_flv.cpp index 11a4f1a03..1f6b7a16c 100644 --- a/trunk/src/app/srs_app_caster_flv.cpp +++ b/trunk/src/app/srs_app_caster_flv.cpp @@ -25,23 +25,66 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef SRS_AUTO_STREAM_CASTER +#include +using namespace std; + #include #include #include #include #include +#include +#include SrsAppCasterFlv::SrsAppCasterFlv(SrsConfDirective* c) { + http_mux = new SrsHttpServeMux(); + output = _srs_config->get_stream_caster_output(c); } SrsAppCasterFlv::~SrsAppCasterFlv() { } +int SrsAppCasterFlv::initialize() +{ + int ret = ERROR_SUCCESS; + + if ((ret = http_mux->handle("/", this)) != ERROR_SUCCESS) { + return ret; + } + + return ret; +} + int SrsAppCasterFlv::on_tcp_client(st_netfd_t stfd) { int ret = ERROR_SUCCESS; + + SrsHttpConn* conn = new SrsHttpConn(this, stfd, http_mux); + conns.push_back(conn); + + if ((ret = conn->start()) != ERROR_SUCCESS) { + return ret; + } + + return ret; +} + +void SrsAppCasterFlv::remove(SrsConnection* c) +{ + std::vector::iterator it; + if ((it = std::find(conns.begin(), conns.end(), c)) != conns.end()) { + conns.erase(it); + } +} + +int SrsAppCasterFlv::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) +{ + int ret = ERROR_SUCCESS; + + srs_trace("flv: handle request at %s", r->path().c_str()); + return ret; } diff --git a/trunk/src/app/srs_app_caster_flv.hpp b/trunk/src/app/srs_app_caster_flv.hpp index 6d0015e8c..fb092f5b2 100644 --- a/trunk/src/app/srs_app_caster_flv.hpp +++ b/trunk/src/app/srs_app_caster_flv.hpp @@ -30,21 +30,41 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include +#include +#include + #ifdef SRS_AUTO_STREAM_CASTER class SrsConfDirective; +class SrsHttpServeMux; +class SrsHttpConn; #include #include +#include +#include -class SrsAppCasterFlv : public ISrsTcpHandler +class SrsAppCasterFlv : virtual public ISrsTcpHandler + , virtual public IConnectionManager, virtual public ISrsHttpHandler { +private: + std::string output; + SrsHttpServeMux* http_mux; + std::vector conns; public: SrsAppCasterFlv(SrsConfDirective* c); virtual ~SrsAppCasterFlv(); +public: + virtual int initialize(); // ISrsTcpHandler public: virtual int on_tcp_client(st_netfd_t stfd); +// IConnectionManager +public: + virtual void remove(SrsConnection* c); +// ISrsHttpHandler +public: + virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); }; #endif diff --git a/trunk/src/app/srs_app_conn.cpp b/trunk/src/app/srs_app_conn.cpp index 656cbe031..4c483ba1c 100644 --- a/trunk/src/app/srs_app_conn.cpp +++ b/trunk/src/app/srs_app_conn.cpp @@ -25,14 +25,21 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -#include #include -SrsConnection::SrsConnection(SrsServer* srs_server, st_netfd_t client_stfd) +IConnectionManager::IConnectionManager() +{ +} + +IConnectionManager::~IConnectionManager() +{ +} + +SrsConnection::SrsConnection(IConnectionManager* cm, st_netfd_t c) { id = 0; - server = srs_server; - stfd = client_stfd; + manager = cm; + stfd = c; // the client thread should reap itself, // so we never use joinable. @@ -86,7 +93,7 @@ int SrsConnection::cycle() void SrsConnection::on_thread_stop() { // TODO: FIXME: never remove itself, use isolate thread to do cleanup. - server->remove(this); + manager->remove(this); } int SrsConnection::srs_id() diff --git a/trunk/src/app/srs_app_conn.hpp b/trunk/src/app/srs_app_conn.hpp index 8cff99a18..29a6eace7 100644 --- a/trunk/src/app/srs_app_conn.hpp +++ b/trunk/src/app/srs_app_conn.hpp @@ -36,7 +36,22 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -class SrsServer; +class SrsConnection; + +/** + * the manager for connection. + */ +class IConnectionManager +{ +public: + IConnectionManager(); + virtual ~IConnectionManager(); +public: + /** + * remove the specified connection. + */ + virtual void remove(SrsConnection* c) = 0; +}; /** * the basic connection of SRS, @@ -57,9 +72,9 @@ private: int id; protected: /** - * the server object to manage the connection. + * the manager object to manage the connection. */ - SrsServer* server; + IConnectionManager* manager; /** * the underlayer st fd handler. */ @@ -69,7 +84,7 @@ protected: */ std::string ip; public: - SrsConnection(SrsServer* srs_server, st_netfd_t client_stfd); + SrsConnection(IConnectionManager* cm, st_netfd_t c); virtual ~SrsConnection(); public: /** diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 5c95af7b0..0f3aac193 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -473,8 +473,8 @@ int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) return srs_go_http_response_json(w, ss.str()); } -SrsHttpApi::SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsHttpServeMux* m) - : SrsConnection(svr, fd) +SrsHttpApi::SrsHttpApi(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m) + : SrsConnection(cm, fd) { mux = m; parser = new SrsHttpParser(); diff --git a/trunk/src/app/srs_app_http_api.hpp b/trunk/src/app/srs_app_http_api.hpp index 6251fa30c..66e971088 100644 --- a/trunk/src/app/srs_app_http_api.hpp +++ b/trunk/src/app/srs_app_http_api.hpp @@ -166,7 +166,7 @@ private: SrsHttpServeMux* mux; bool crossdomain_required; public: - SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsHttpServeMux* m); + SrsHttpApi(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m); virtual ~SrsHttpApi(); // interface IKbpsDelta public: diff --git a/trunk/src/app/srs_app_http_conn.cpp b/trunk/src/app/srs_app_http_conn.cpp index 43fa69e0b..c6f4b94b5 100644 --- a/trunk/src/app/srs_app_http_conn.cpp +++ b/trunk/src/app/srs_app_http_conn.cpp @@ -1334,11 +1334,11 @@ int SrsHttpServer::initialize_hls_streaming() return ret; } -SrsHttpConn::SrsHttpConn(SrsServer* svr, st_netfd_t fd, SrsHttpServer* m) - : SrsConnection(svr, fd) +SrsHttpConn::SrsHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m) + : SrsConnection(cm, fd) { parser = new SrsHttpParser(); - http_server = m; + http_mux = m; } SrsHttpConn::~SrsHttpConn() @@ -1424,7 +1424,7 @@ int SrsHttpConn::process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r) r->method_str().c_str(), r->url().c_str(), r->content_length()); // use default server mux to serve http request. - if ((ret = http_server->mux.serve_http(w, r)) != ERROR_SUCCESS) { + if ((ret = http_mux->serve_http(w, r)) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { srs_error("serve http msg failed. ret=%d", ret); } diff --git a/trunk/src/app/srs_app_http_conn.hpp b/trunk/src/app/srs_app_http_conn.hpp index 418364294..63f87a5ff 100644 --- a/trunk/src/app/srs_app_http_conn.hpp +++ b/trunk/src/app/srs_app_http_conn.hpp @@ -39,6 +39,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +class SrsServer; class SrsSource; class SrsRequest; class SrsConsumer; @@ -375,9 +376,9 @@ class SrsHttpConn : public SrsConnection { private: SrsHttpParser* parser; - SrsHttpServer* http_server; + SrsHttpServeMux* http_mux; public: - SrsHttpConn(SrsServer* svr, st_netfd_t fd, SrsHttpServer* m); + SrsHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m); virtual ~SrsHttpConn(); // interface IKbpsDelta public: diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index 588a6cdf4..6b0583f49 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -75,12 +75,13 @@ using namespace std; // when edge timeout, retry next. #define SRS_EDGE_TOKEN_TRAVERSE_TIMEOUT_US (int64_t)(3*1000*1000LL) -SrsRtmpConn::SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd) - : SrsConnection(srs_server, client_stfd) +SrsRtmpConn::SrsRtmpConn(SrsServer* svr, st_netfd_t c) + : SrsConnection(svr, c) { + server = svr; req = new SrsRequest(); res = new SrsResponse(); - skt = new SrsStSocket(client_stfd); + skt = new SrsStSocket(c); rtmp = new SrsRtmpServer(skt); refer = new SrsRefer(); bandwidth = new SrsBandwidth(); diff --git a/trunk/src/app/srs_app_rtmp_conn.hpp b/trunk/src/app/srs_app_rtmp_conn.hpp index 7c1a2205a..39aad6e0e 100644 --- a/trunk/src/app/srs_app_rtmp_conn.hpp +++ b/trunk/src/app/srs_app_rtmp_conn.hpp @@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +class SrsServer; class SrsRtmpServer; class SrsRequest; class SrsResponse; @@ -61,6 +62,7 @@ class SrsRtmpConn : public virtual SrsConnection, public virtual ISrsReloadHandl // for the thread to directly access any field of connection. friend class SrsPublishRecvThread; private: + SrsServer* server; SrsRequest* req; SrsResponse* res; SrsStSocket* skt; @@ -81,7 +83,7 @@ private: // @see https://github.com/simple-rtmp-server/srs/issues/257 bool realtime; public: - SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd); + SrsRtmpConn(SrsServer* svr, st_netfd_t c); virtual ~SrsRtmpConn(); protected: virtual int do_cycle(); diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index b522c2545..851c8023c 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -106,6 +106,8 @@ std::string srs_listener_type2string(SrsListenerType type) return "MPEG-TS over UDP"; case SrsListenerRtsp: return "RTSP"; + case SrsListenerFlv: + return "HTTP-FLV"; default: return "UNKONWN"; } @@ -238,8 +240,8 @@ SrsHttpFlvListener::SrsHttpFlvListener(SrsServer* server, SrsListenerType type, // the caller already ensure the type is ok, // we just assert here for unknown stream caster. - srs_assert(_type == SrsListenerRtsp); - if (_type == SrsListenerRtsp) { + srs_assert(_type == SrsListenerFlv); + if (_type == SrsListenerFlv) { caster = new SrsAppCasterFlv(c); } } @@ -256,11 +258,15 @@ int SrsHttpFlvListener::listen(string ip, int port) // the caller already ensure the type is ok, // we just assert here for unknown stream caster. - srs_assert(_type == SrsListenerRtsp); + srs_assert(_type == SrsListenerFlv); _ip = ip; _port = port; + if ((ret = caster->initialize()) != ERROR_SUCCESS) { + return ret; + } + srs_freep(listener); listener = new SrsTcpListener(this, ip, port); @@ -1157,7 +1163,7 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd) #endif } else if (type == SrsListenerHttpStream) { #ifdef SRS_AUTO_HTTP_SERVER - conn = new SrsHttpConn(this, client_stfd, http_stream_mux); + conn = new SrsHttpConn(this, client_stfd, &http_stream_mux->mux); #else srs_warn("close http client for server not support http-server"); srs_close_stfd(client_stfd); diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index b2ecafbb1..1ff7cee90 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include class SrsServer; class SrsConnection; @@ -51,6 +52,9 @@ class ISrsTcpHandler; class ISrsUdpHandler; class SrsUdpListener; class SrsTcpListener; +#ifdef SRS_AUTO_STREAM_CASTER +class SrsAppCasterFlv; +#endif // listener type for server to identify the connection, // that is, use different type to process the connection. @@ -66,7 +70,7 @@ enum SrsListenerType SrsListenerMpegTsOverUdp = 3, // TCP stream, RTSP stream. SrsListenerRtsp = 4, - // HTTP stream, FLV over HTTP POST. + // TCP stream, FLV stream over HTTP. SrsListenerFlv = 5, }; @@ -126,13 +130,13 @@ public: }; /** - * the tcp listener, for http flv server. + * the tcp listener, for flv stream server. */ class SrsHttpFlvListener : virtual public SrsListener, virtual public ISrsTcpHandler { private: SrsTcpListener* listener; - ISrsTcpHandler* caster; + SrsAppCasterFlv* caster; public: SrsHttpFlvListener(SrsServer* server, SrsListenerType type, SrsConfDirective* c); virtual ~SrsHttpFlvListener(); @@ -215,6 +219,7 @@ public: */ class SrsServer : virtual public ISrsReloadHandler , virtual public ISrsSourceHandler, virtual public ISrsHlsHandler + , virtual public IConnectionManager { private: #ifdef SRS_AUTO_HTTP_API @@ -279,7 +284,7 @@ public: virtual int http_handle(); virtual int ingest(); virtual int cycle(); -// server utility +// IConnectionManager public: /** * callback for connection to remove itself. @@ -287,6 +292,8 @@ public: * @see SrsConnection.on_thread_stop(). */ virtual void remove(SrsConnection* conn); +// server utilities. +public: /** * callback for signal manager got a signal. * the signal manager convert signal to io message, From a95fd6d1400ddf900b8c55e4988e0896b20b09a7 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2015 23:57:22 +0800 Subject: [PATCH 3/3] read the http flv stream. --- trunk/src/app/srs_app_caster_flv.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/trunk/src/app/srs_app_caster_flv.cpp b/trunk/src/app/srs_app_caster_flv.cpp index 1f6b7a16c..e57d0a044 100644 --- a/trunk/src/app/srs_app_caster_flv.cpp +++ b/trunk/src/app/srs_app_caster_flv.cpp @@ -35,6 +35,7 @@ using namespace std; #include #include #include +#include SrsAppCasterFlv::SrsAppCasterFlv(SrsConfDirective* c) { @@ -78,12 +79,24 @@ void SrsAppCasterFlv::remove(SrsConnection* c) conns.erase(it); } } - +#define SRS_HTTP_FLV_STREAM_BUFFER 4096 int SrsAppCasterFlv::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) { int ret = ERROR_SUCCESS; - srs_trace("flv: handle request at %s", r->path().c_str()); + srs_info("flv: handle request at %s", r->path().c_str()); + + char* buffer = new char[SRS_HTTP_FLV_STREAM_BUFFER]; + SrsAutoFree(char, buffer); + + ISrsHttpResponseReader* rr = r->body_reader(); + while (!rr->eof()) { + int nb_read = 0; + if ((ret = rr->read(buffer, SRS_HTTP_FLV_STREAM_BUFFER, &nb_read)) != ERROR_SUCCESS) { + return ret; + } + srs_trace("flv: read %dB from %s", nb_read, r->path().c_str()); + } return ret; }