mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
for #133, create rtsp framework.
This commit is contained in:
parent
e81e090239
commit
c0e50265bd
11 changed files with 348 additions and 26 deletions
|
@ -157,8 +157,8 @@ stream_caster {
|
||||||
# rtmp://127.0.0.1/live/livestream
|
# rtmp://127.0.0.1/live/livestream
|
||||||
output rtmp://127.0.0.1/live/livestream;
|
output rtmp://127.0.0.1/live/livestream;
|
||||||
# the listen port for stream caster.
|
# the listen port for stream caster.
|
||||||
# for mpegts_over_udp caster, listen at udp port.
|
# for mpegts_over_udp caster, listen at udp port. for example, 8935.
|
||||||
# for rtsp caster, listen at tcp port.
|
# for rtsp caster, listen at tcp port. for example, 554.
|
||||||
listen 8935;
|
listen 8935;
|
||||||
}
|
}
|
||||||
stream_caster {
|
stream_caster {
|
||||||
|
@ -168,7 +168,7 @@ stream_caster {
|
||||||
listen 8935;
|
listen 8935;
|
||||||
}
|
}
|
||||||
stream_caster {
|
stream_caster {
|
||||||
enabled on;
|
enabled off;
|
||||||
caster rtsp;
|
caster rtsp;
|
||||||
output rtmp://127.0.0.1/[app]/[stream];
|
output rtmp://127.0.0.1/[app]/[stream];
|
||||||
listen 554;
|
listen 554;
|
||||||
|
|
2
trunk/configure
vendored
2
trunk/configure
vendored
|
@ -376,7 +376,7 @@ MODULE_DEPENDS=("CORE" "KERNEL")
|
||||||
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot})
|
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot})
|
||||||
MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack" "srs_rtmp_sdk"
|
MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack" "srs_rtmp_sdk"
|
||||||
"srs_rtmp_handshake" "srs_rtmp_utility" "srs_rtmp_msg_array" "srs_rtmp_buffer"
|
"srs_rtmp_handshake" "srs_rtmp_utility" "srs_rtmp_msg_array" "srs_rtmp_buffer"
|
||||||
"srs_raw_avc")
|
"srs_raw_avc" "srs_rtsp_stack")
|
||||||
RTMP_INCS="src/protocol"; MODULE_DIR=${RTMP_INCS} . auto/modules.sh
|
RTMP_INCS="src/protocol"; MODULE_DIR=${RTMP_INCS} . auto/modules.sh
|
||||||
RTMP_OBJS="${MODULE_OBJS[@]}"
|
RTMP_OBJS="${MODULE_OBJS[@]}"
|
||||||
#
|
#
|
||||||
|
|
|
@ -36,6 +36,8 @@ file
|
||||||
../../src/kernel/srs_kernel_log.cpp,
|
../../src/kernel/srs_kernel_log.cpp,
|
||||||
../../src/kernel/srs_kernel_mp3.hpp,
|
../../src/kernel/srs_kernel_mp3.hpp,
|
||||||
../../src/kernel/srs_kernel_mp3.cpp,
|
../../src/kernel/srs_kernel_mp3.cpp,
|
||||||
|
../../src/kernel/srs_rtsp_stack.hpp,
|
||||||
|
../../src/kernel/srs_rtsp_stack.cpp,
|
||||||
../../src/kernel/srs_kernel_stream.hpp,
|
../../src/kernel/srs_kernel_stream.hpp,
|
||||||
../../src/kernel/srs_kernel_stream.cpp,
|
../../src/kernel/srs_kernel_stream.cpp,
|
||||||
../../src/kernel/srs_kernel_ts.cpp,
|
../../src/kernel/srs_kernel_ts.cpp,
|
||||||
|
|
|
@ -89,6 +89,7 @@
|
||||||
<ClInclude Include="..\..\src\app\srs_app_refer.hpp" />
|
<ClInclude Include="..\..\src\app\srs_app_refer.hpp" />
|
||||||
<ClInclude Include="..\..\src\app\srs_app_reload.hpp" />
|
<ClInclude Include="..\..\src\app\srs_app_reload.hpp" />
|
||||||
<ClInclude Include="..\..\src\app\srs_app_rtmp_conn.hpp" />
|
<ClInclude Include="..\..\src\app\srs_app_rtmp_conn.hpp" />
|
||||||
|
<ClInclude Include="..\..\src\app\srs_app_rtsp.hpp" />
|
||||||
<ClInclude Include="..\..\src\app\srs_app_security.hpp" />
|
<ClInclude Include="..\..\src\app\srs_app_security.hpp" />
|
||||||
<ClInclude Include="..\..\src\app\srs_app_server.hpp" />
|
<ClInclude Include="..\..\src\app\srs_app_server.hpp" />
|
||||||
<ClInclude Include="..\..\src\app\srs_app_source.hpp" />
|
<ClInclude Include="..\..\src\app\srs_app_source.hpp" />
|
||||||
|
@ -125,6 +126,7 @@
|
||||||
<ClInclude Include="..\..\src\protocol\srs_rtmp_sdk.hpp" />
|
<ClInclude Include="..\..\src\protocol\srs_rtmp_sdk.hpp" />
|
||||||
<ClInclude Include="..\..\src\protocol\srs_rtmp_stack.hpp" />
|
<ClInclude Include="..\..\src\protocol\srs_rtmp_stack.hpp" />
|
||||||
<ClInclude Include="..\..\src\protocol\srs_rtmp_utility.hpp" />
|
<ClInclude Include="..\..\src\protocol\srs_rtmp_utility.hpp" />
|
||||||
|
<ClInclude Include="..\..\src\protocol\srs_rtsp_stack.hpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\research\hls\ts_info.cc" />
|
<ClCompile Include="..\..\research\hls\ts_info.cc" />
|
||||||
|
@ -166,6 +168,7 @@
|
||||||
<ClCompile Include="..\..\src\app\srs_app_refer.cpp" />
|
<ClCompile Include="..\..\src\app\srs_app_refer.cpp" />
|
||||||
<ClCompile Include="..\..\src\app\srs_app_reload.cpp" />
|
<ClCompile Include="..\..\src\app\srs_app_reload.cpp" />
|
||||||
<ClCompile Include="..\..\src\app\srs_app_rtmp_conn.cpp" />
|
<ClCompile Include="..\..\src\app\srs_app_rtmp_conn.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\app\srs_app_rtsp.cpp" />
|
||||||
<ClCompile Include="..\..\src\app\srs_app_security.cpp" />
|
<ClCompile Include="..\..\src\app\srs_app_security.cpp" />
|
||||||
<ClCompile Include="..\..\src\app\srs_app_server.cpp" />
|
<ClCompile Include="..\..\src\app\srs_app_server.cpp" />
|
||||||
<ClCompile Include="..\..\src\app\srs_app_source.cpp" />
|
<ClCompile Include="..\..\src\app\srs_app_source.cpp" />
|
||||||
|
@ -203,6 +206,7 @@
|
||||||
<ClCompile Include="..\..\src\protocol\srs_rtmp_sdk.cpp" />
|
<ClCompile Include="..\..\src\protocol\srs_rtmp_sdk.cpp" />
|
||||||
<ClCompile Include="..\..\src\protocol\srs_rtmp_stack.cpp" />
|
<ClCompile Include="..\..\src\protocol\srs_rtmp_stack.cpp" />
|
||||||
<ClCompile Include="..\..\src\protocol\srs_rtmp_utility.cpp" />
|
<ClCompile Include="..\..\src\protocol\srs_rtmp_utility.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\protocol\srs_rtsp_stack.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
|
@ -229,6 +229,12 @@
|
||||||
<ClCompile Include="..\..\src\protocol\srs_raw_avc.cpp">
|
<ClCompile Include="..\..\src\protocol\srs_raw_avc.cpp">
|
||||||
<Filter>srs</Filter>
|
<Filter>srs</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\app\srs_app_rtsp.cpp">
|
||||||
|
<Filter>srs</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\protocol\srs_rtsp_stack.cpp">
|
||||||
|
<Filter>srs</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\app\srs_app_bandwidth.hpp">
|
<ClInclude Include="..\..\src\app\srs_app_bandwidth.hpp">
|
||||||
|
@ -420,6 +426,12 @@
|
||||||
<ClInclude Include="..\..\src\protocol\srs_raw_avc.hpp">
|
<ClInclude Include="..\..\src\protocol\srs_raw_avc.hpp">
|
||||||
<Filter>srs</Filter>
|
<Filter>srs</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\app\srs_app_rtsp.hpp">
|
||||||
|
<Filter>srs</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\protocol\srs_rtsp_stack.hpp">
|
||||||
|
<Filter>srs</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="research">
|
<Filter Include="research">
|
||||||
|
|
|
@ -23,7 +23,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#include <srs_app_rtsp.hpp>
|
#include <srs_app_rtsp.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
#include <srs_app_config.hpp>
|
#include <srs_app_config.hpp>
|
||||||
|
#include <srs_kernel_error.hpp>
|
||||||
|
#include <srs_rtsp_stack.hpp>
|
||||||
|
#include <srs_app_st_socket.hpp>
|
||||||
|
#include <srs_kernel_log.hpp>
|
||||||
|
#include <srs_app_utility.hpp>
|
||||||
|
|
||||||
#ifdef SRS_AUTO_STREAM_CASTER
|
#ifdef SRS_AUTO_STREAM_CASTER
|
||||||
|
|
||||||
|
@ -35,13 +43,115 @@ ISrsRtspHandler::~ISrsRtspHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsRtspConn::SrsRtspConn(SrsConfDirective* c)
|
SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o)
|
||||||
{
|
{
|
||||||
output = _srs_config->get_stream_caster_output(c);
|
output = o;
|
||||||
|
caster = c;
|
||||||
|
stfd = fd;
|
||||||
|
skt = new SrsStSocket(fd);
|
||||||
|
rtsp = new SrsRtspStack(skt);
|
||||||
|
trd = new SrsThread("rtsp", this, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsRtspConn::~SrsRtspConn()
|
SrsRtspConn::~SrsRtspConn()
|
||||||
{
|
{
|
||||||
|
srs_close_stfd(stfd);
|
||||||
|
trd->stop();
|
||||||
|
|
||||||
|
srs_freep(trd);
|
||||||
|
srs_freep(skt);
|
||||||
|
srs_freep(rtsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsRtspConn::serve()
|
||||||
|
{
|
||||||
|
return trd->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsRtspConn::do_cycle()
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// retrieve ip of client.
|
||||||
|
std::string ip = srs_get_peer_ip(st_netfd_fileno(stfd));
|
||||||
|
srs_trace("rtsp: serve %s", ip.c_str());
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsRtspConn::cycle()
|
||||||
|
{
|
||||||
|
// serve the rtsp client.
|
||||||
|
int ret = do_cycle();
|
||||||
|
|
||||||
|
// if socket io error, set to closed.
|
||||||
|
if (srs_is_client_gracefully_close(ret)) {
|
||||||
|
ret = ERROR_SOCKET_CLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// success.
|
||||||
|
if (ret == ERROR_SUCCESS) {
|
||||||
|
srs_trace("client finished.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// client close peer.
|
||||||
|
if (ret == ERROR_SOCKET_CLOSED) {
|
||||||
|
srs_warn("client disconnect peer. ret=%d", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// terminate thread in the thread cycle itself.
|
||||||
|
trd->stop_loop();
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsRtspConn::on_thread_stop()
|
||||||
|
{
|
||||||
|
caster->remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c)
|
||||||
|
{
|
||||||
|
// TODO: FIXME: support reload.
|
||||||
|
output = _srs_config->get_stream_caster_output(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsRtspCaster::~SrsRtspCaster()
|
||||||
|
{
|
||||||
|
std::vector<SrsRtspConn*>::iterator it;
|
||||||
|
for (it = clients.begin(); it != clients.end(); ++it) {
|
||||||
|
SrsRtspConn* conn = *it;
|
||||||
|
srs_freep(conn);
|
||||||
|
}
|
||||||
|
clients.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsRtspCaster::serve_client(st_netfd_t stfd)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
SrsRtspConn* conn = new SrsRtspConn(this, stfd, output);
|
||||||
|
if ((ret = conn->serve()) != ERROR_SUCCESS) {
|
||||||
|
srs_error("rtsp: serve client failed. ret=%d", ret);
|
||||||
|
srs_freep(conn);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.push_back(conn);
|
||||||
|
srs_info("rtsp: start thread to serve client.");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsRtspCaster::remove(SrsRtspConn* conn)
|
||||||
|
{
|
||||||
|
std::vector<SrsRtspConn*>::iterator it = find(clients.begin(), clients.end(), conn);
|
||||||
|
if (it != clients.end()) {
|
||||||
|
clients.erase(it);
|
||||||
|
}
|
||||||
|
srs_info("rtsp: remove connection from caster.");
|
||||||
|
|
||||||
|
srs_freep(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,10 +31,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <srs_core.hpp>
|
#include <srs_core.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <srs_app_st.hpp>
|
||||||
|
#include <srs_app_thread.hpp>
|
||||||
|
|
||||||
#ifdef SRS_AUTO_STREAM_CASTER
|
#ifdef SRS_AUTO_STREAM_CASTER
|
||||||
|
|
||||||
class SrsConfDirective;
|
class SrsConfDirective;
|
||||||
|
class SrsStSocket;
|
||||||
|
class SrsRtspStack;
|
||||||
|
class SrsRtspCaster;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the handler for rtsp handler.
|
* the handler for rtsp handler.
|
||||||
|
@ -44,18 +51,54 @@ class ISrsRtspHandler
|
||||||
public:
|
public:
|
||||||
ISrsRtspHandler();
|
ISrsRtspHandler();
|
||||||
virtual ~ISrsRtspHandler();
|
virtual ~ISrsRtspHandler();
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* serve the rtsp connection.
|
||||||
|
*/
|
||||||
|
virtual int serve_client(st_netfd_t stfd) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the connection for rtsp.
|
* the rtsp connection serve the fd.
|
||||||
*/
|
*/
|
||||||
class SrsRtspConn : public ISrsRtspHandler
|
class SrsRtspConn : public ISrsThreadHandler
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string output;
|
std::string output;
|
||||||
|
st_netfd_t stfd;
|
||||||
|
SrsStSocket* skt;
|
||||||
|
SrsRtspStack* rtsp;
|
||||||
|
SrsRtspCaster* caster;
|
||||||
|
SrsThread* trd;
|
||||||
public:
|
public:
|
||||||
SrsRtspConn(SrsConfDirective* c);
|
SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o);
|
||||||
virtual ~SrsRtspConn();
|
virtual ~SrsRtspConn();
|
||||||
|
public:
|
||||||
|
virtual int serve();
|
||||||
|
private:
|
||||||
|
virtual int do_cycle();
|
||||||
|
// interface ISrsThreadHandler
|
||||||
|
public:
|
||||||
|
virtual int cycle();
|
||||||
|
virtual void on_thread_stop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the caster for rtsp.
|
||||||
|
*/
|
||||||
|
class SrsRtspCaster : public ISrsRtspHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string output;
|
||||||
|
std::vector<SrsRtspConn*> clients;
|
||||||
|
public:
|
||||||
|
SrsRtspCaster(SrsConfDirective* c);
|
||||||
|
virtual ~SrsRtspCaster();
|
||||||
|
public:
|
||||||
|
virtual int serve_client(st_netfd_t stfd);
|
||||||
|
// internal methods.
|
||||||
|
public:
|
||||||
|
virtual void remove(SrsRtspConn* conn);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -240,7 +240,7 @@ SrsRtspListener::SrsRtspListener(SrsServer* server, SrsListenerType type, SrsCon
|
||||||
// we just assert here for unknown stream caster.
|
// we just assert here for unknown stream caster.
|
||||||
srs_assert(_type == SrsListenerRtsp);
|
srs_assert(_type == SrsListenerRtsp);
|
||||||
if (_type == SrsListenerRtsp) {
|
if (_type == SrsListenerRtsp) {
|
||||||
caster = new SrsRtspConn(c);
|
caster = new SrsRtspCaster(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ int SrsRtspListener::cycle()
|
||||||
}
|
}
|
||||||
srs_verbose("get a client. fd=%d", st_netfd_fileno(client_stfd));
|
srs_verbose("get a client. fd=%d", st_netfd_fileno(client_stfd));
|
||||||
|
|
||||||
if ((ret = _server->accept_client(_type, client_stfd)) != ERROR_SUCCESS) {
|
if ((ret = caster->serve_client(client_stfd)) != ERROR_SUCCESS) {
|
||||||
srs_warn("accept client error. ret=%d", ret);
|
srs_warn("accept client error. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,22 +46,78 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
* which will cause the socket to return error and
|
* which will cause the socket to return error and
|
||||||
* terminate the cycle thread.
|
* terminate the cycle thread.
|
||||||
*
|
*
|
||||||
* when thread interrupt, the socket maybe not got EINT,
|
* Usage 1: stop by other thread.
|
||||||
* espectially on st_usleep(), so the cycle must check the loop,
|
* user can create thread and stop then start again and again,
|
||||||
* when handler->cycle() has loop itself, for example:
|
* generally must provides a start and stop method, @see SrsIngester.
|
||||||
* while (true):
|
* the step to create a thread stop by other thread:
|
||||||
* if (read_from_socket(skt) < 0) break;
|
* 1. create SrsThread field, with joinable true.
|
||||||
* if thread stop when read_from_socket, it's ok, the loop will break,
|
* 2. must use stop to stop and join the thread.
|
||||||
* but when thread stop interrupt the s_usleep(0), then the loop is
|
* for example:
|
||||||
* death loop.
|
* class SrsIngester : public ISrsThreadHandler {
|
||||||
* in a word, the handler->cycle() must:
|
* public: SrsIngester() { pthread = new SrsThread("ingest", this, SRS_AUTO_INGESTER_SLEEP_US, true); }
|
||||||
* while (pthread->can_loop()):
|
* public: virtual int start() { return pthread->start(); }
|
||||||
* if (read_from_socket(skt) < 0) break;
|
* public: virtual void stop() { pthread->stop(); }
|
||||||
* check the loop, then it works.
|
* public: virtual int cycle() {
|
||||||
|
* // check status, start ffmpeg when stopped.
|
||||||
|
* }
|
||||||
|
* };
|
||||||
*
|
*
|
||||||
* in the thread itself, that is the cycle method,
|
* Usage 2: stop by thread itself.
|
||||||
* if itself want to terminate the thread, should never use stop(),
|
* user can create thread which stop itself,
|
||||||
* but use stop_loop() to set the loop to false and terminate normally.
|
* generally only need to provides a start method,
|
||||||
|
* the object will destroy itself then terminate the thread, @see SrsConnection
|
||||||
|
* 1. create SrsThread field, with joinable false.
|
||||||
|
* 2. owner stop thread loop, destroy itself when thread stop.
|
||||||
|
* for example:
|
||||||
|
* class SrsConnection : public ISrsThreadHandler {
|
||||||
|
* public: SrsConnection() { pthread = new SrsThread("conn", this, 0, false); }
|
||||||
|
* public: virtual int start() { return pthread->start(); }
|
||||||
|
* public: virtual int cycle() {
|
||||||
|
* // serve client.
|
||||||
|
* // set loop to stop to quit, stop thread itself.
|
||||||
|
* pthread->stop_loop();
|
||||||
|
* }
|
||||||
|
* public: virtual int on_thread_stop() {
|
||||||
|
* // remove the connection in thread itself.
|
||||||
|
* server->remove(this);
|
||||||
|
* }
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* Usage 3: loop in the cycle method.
|
||||||
|
* user can use loop code in the cycle method, @see SrsForwarder
|
||||||
|
* 1. create SrsThread field, with or without joinable is ok.
|
||||||
|
* 2. loop code in cycle method, check the can_loop() for thread to quit.
|
||||||
|
* for example:
|
||||||
|
* class SrsForwarder : public ISrsThreadHandler {
|
||||||
|
* public: virtual int cycle() {
|
||||||
|
* while (pthread->can_loop()) {
|
||||||
|
* // read msgs from queue and forward to server.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* @remark why should check can_loop() in cycle method?
|
||||||
|
* when thread interrupt, the socket maybe not got EINT,
|
||||||
|
* espectially on st_usleep(), so the cycle must check the loop,
|
||||||
|
* when handler->cycle() has loop itself, for example:
|
||||||
|
* while (true):
|
||||||
|
* if (read_from_socket(skt) < 0) break;
|
||||||
|
* if thread stop when read_from_socket, it's ok, the loop will break,
|
||||||
|
* but when thread stop interrupt the s_usleep(0), then the loop is
|
||||||
|
* death loop.
|
||||||
|
* in a word, the handler->cycle() must:
|
||||||
|
* while (pthread->can_loop()):
|
||||||
|
* if (read_from_socket(skt) < 0) break;
|
||||||
|
* check the loop, then it works.
|
||||||
|
*
|
||||||
|
* @remark why should use stop_loop() to terminate thread in itself?
|
||||||
|
* in the thread itself, that is the cycle method,
|
||||||
|
* if itself want to terminate the thread, should never use stop(),
|
||||||
|
* but use stop_loop() to set the loop to false and terminate normally.
|
||||||
|
*
|
||||||
|
* @remark when should set the interval_us, and when not?
|
||||||
|
* the cycle will invoke util cannot loop, eventhough the return code of cycle is error,
|
||||||
|
* so the interval_us used to sleep for each cycle.
|
||||||
*/
|
*/
|
||||||
class ISrsThreadHandler
|
class ISrsThreadHandler
|
||||||
{
|
{
|
||||||
|
|
40
trunk/src/protocol/srs_rtsp_stack.cpp
Normal file
40
trunk/src/protocol/srs_rtsp_stack.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013-2015 winlin
|
||||||
|
|
||||||
|
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 <srs_rtsp_stack.hpp>
|
||||||
|
|
||||||
|
#include <srs_rtmp_io.hpp>
|
||||||
|
|
||||||
|
#ifdef SRS_AUTO_STREAM_CASTER
|
||||||
|
|
||||||
|
SrsRtspStack::SrsRtspStack(ISrsProtocolReaderWriter* s)
|
||||||
|
{
|
||||||
|
skt = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsRtspStack::~SrsRtspStack()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
55
trunk/src/protocol/srs_rtsp_stack.hpp
Normal file
55
trunk/src/protocol/srs_rtsp_stack.hpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013-2015 winlin
|
||||||
|
|
||||||
|
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_PROTOCOL_RTSP_STACK_HPP
|
||||||
|
#define SRS_PROTOCOL_RTSP_STACK_HPP
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <srs_rtsp_stack.hpp>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <srs_core.hpp>
|
||||||
|
|
||||||
|
#ifdef SRS_AUTO_STREAM_CASTER
|
||||||
|
|
||||||
|
class ISrsProtocolReaderWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the rtsp protocol stack to parse the rtsp packets.
|
||||||
|
*/
|
||||||
|
class SrsRtspStack
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* underlayer socket object, send/recv bytes.
|
||||||
|
*/
|
||||||
|
ISrsProtocolReaderWriter* skt;
|
||||||
|
public:
|
||||||
|
SrsRtspStack(ISrsProtocolReaderWriter* s);
|
||||||
|
virtual ~SrsRtspStack();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue