正在显示
9 个修改的文件
包含
183 行增加
和
38 行删除
| @@ -77,8 +77,9 @@ SrsUdpListener::SrsUdpListener(ISrsUdpHandler* h, int p) | @@ -77,8 +77,9 @@ SrsUdpListener::SrsUdpListener(ISrsUdpHandler* h, int p) | ||
| 77 | 77 | ||
| 78 | SrsUdpListener::~SrsUdpListener() | 78 | SrsUdpListener::~SrsUdpListener() |
| 79 | { | 79 | { |
| 80 | + // close the stfd to trigger thread to interrupted. | ||
| 80 | srs_close_stfd(stfd); | 81 | srs_close_stfd(stfd); |
| 81 | - | 82 | + |
| 82 | pthread->stop(); | 83 | pthread->stop(); |
| 83 | srs_freep(pthread); | 84 | srs_freep(pthread); |
| 84 | 85 | ||
| @@ -143,8 +144,8 @@ int SrsUdpListener::listen() | @@ -143,8 +144,8 @@ int SrsUdpListener::listen() | ||
| 143 | int SrsUdpListener::cycle() | 144 | int SrsUdpListener::cycle() |
| 144 | { | 145 | { |
| 145 | int ret = ERROR_SUCCESS; | 146 | int ret = ERROR_SUCCESS; |
| 146 | - | ||
| 147 | - for (;;) { | 147 | + |
| 148 | + while (pthread->can_loop()) { | ||
| 148 | // TODO: FIXME: support ipv6, @see man 7 ipv6 | 149 | // TODO: FIXME: support ipv6, @see man 7 ipv6 |
| 149 | sockaddr_in from; | 150 | sockaddr_in from; |
| 150 | int nb_from = sizeof(sockaddr_in); | 151 | int nb_from = sizeof(sockaddr_in); |
| @@ -181,8 +182,9 @@ SrsTcpListener::SrsTcpListener(ISrsTcpHandler* h, int p) | @@ -181,8 +182,9 @@ SrsTcpListener::SrsTcpListener(ISrsTcpHandler* h, int p) | ||
| 181 | 182 | ||
| 182 | SrsTcpListener::~SrsTcpListener() | 183 | SrsTcpListener::~SrsTcpListener() |
| 183 | { | 184 | { |
| 185 | + // close the stfd to trigger thread to interrupted. | ||
| 184 | srs_close_stfd(stfd); | 186 | srs_close_stfd(stfd); |
| 185 | - | 187 | + |
| 186 | pthread->stop(); | 188 | pthread->stop(); |
| 187 | srs_freep(pthread); | 189 | srs_freep(pthread); |
| 188 | 190 |
| @@ -36,21 +36,41 @@ using namespace std; | @@ -36,21 +36,41 @@ using namespace std; | ||
| 36 | 36 | ||
| 37 | #ifdef SRS_AUTO_STREAM_CASTER | 37 | #ifdef SRS_AUTO_STREAM_CASTER |
| 38 | 38 | ||
| 39 | -ISrsRtspHandler::ISrsRtspHandler() | 39 | +SrsRtpConn::SrsRtpConn(SrsRtspConn* r, int p) |
| 40 | { | 40 | { |
| 41 | + rtsp = r; | ||
| 42 | + _port = p; | ||
| 43 | + listener = new SrsUdpListener(this, p); | ||
| 41 | } | 44 | } |
| 42 | 45 | ||
| 43 | -ISrsRtspHandler::~ISrsRtspHandler() | 46 | +SrsRtpConn::~SrsRtpConn() |
| 44 | { | 47 | { |
| 48 | + srs_freep(listener); | ||
| 45 | } | 49 | } |
| 46 | 50 | ||
| 47 | -SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o, int lpmin, int lpmax) | 51 | +int SrsRtpConn::port() |
| 52 | +{ | ||
| 53 | + return _port; | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +int SrsRtpConn::listen() | ||
| 57 | +{ | ||
| 58 | + return listener->listen(); | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) | ||
| 62 | +{ | ||
| 63 | + int ret = ERROR_SUCCESS; | ||
| 64 | + return ret; | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) | ||
| 48 | { | 68 | { |
| 49 | output = o; | 69 | output = o; |
| 50 | - local_port_min = lpmin; | ||
| 51 | - local_port_max = lpmax; | ||
| 52 | 70 | ||
| 53 | session = "O9EaZ4bf"; // TODO: FIXME: generate session id. | 71 | session = "O9EaZ4bf"; // TODO: FIXME: generate session id. |
| 72 | + video_rtp = NULL; | ||
| 73 | + audio_rtp = NULL; | ||
| 54 | 74 | ||
| 55 | caster = c; | 75 | caster = c; |
| 56 | stfd = fd; | 76 | stfd = fd; |
| @@ -64,6 +84,9 @@ SrsRtspConn::~SrsRtspConn() | @@ -64,6 +84,9 @@ SrsRtspConn::~SrsRtspConn() | ||
| 64 | srs_close_stfd(stfd); | 84 | srs_close_stfd(stfd); |
| 65 | trd->stop(); | 85 | trd->stop(); |
| 66 | 86 | ||
| 87 | + srs_freep(video_rtp); | ||
| 88 | + srs_freep(audio_rtp); | ||
| 89 | + | ||
| 67 | srs_freep(trd); | 90 | srs_freep(trd); |
| 68 | srs_freep(skt); | 91 | srs_freep(skt); |
| 69 | srs_freep(rtsp); | 92 | srs_freep(rtsp); |
| @@ -103,6 +126,8 @@ int SrsRtspConn::do_cycle() | @@ -103,6 +126,8 @@ int SrsRtspConn::do_cycle() | ||
| 103 | } | 126 | } |
| 104 | } else if (req->is_announce()) { | 127 | } else if (req->is_announce()) { |
| 105 | srs_assert(req->sdp); | 128 | srs_assert(req->sdp); |
| 129 | + video_id = req->sdp->video_stream_id; | ||
| 130 | + audio_id = req->sdp->audio_stream_id; | ||
| 106 | sps = req->sdp->video_sps; | 131 | sps = req->sdp->video_sps; |
| 107 | pps = req->sdp->video_pps; | 132 | pps = req->sdp->video_pps; |
| 108 | asc = req->sdp->audio_sh; | 133 | asc = req->sdp->audio_sh; |
| @@ -119,11 +144,31 @@ int SrsRtspConn::do_cycle() | @@ -119,11 +144,31 @@ int SrsRtspConn::do_cycle() | ||
| 119 | } | 144 | } |
| 120 | } else if (req->is_setup()) { | 145 | } else if (req->is_setup()) { |
| 121 | srs_assert(req->transport); | 146 | srs_assert(req->transport); |
| 147 | + int lpm = 0; | ||
| 148 | + if ((ret = caster->alloc_port(&lpm)) != ERROR_SUCCESS) { | ||
| 149 | + srs_error("rtsp: alloc port failed. ret=%d", ret); | ||
| 150 | + return ret; | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + SrsRtpConn* rtp = NULL; | ||
| 154 | + if (req->stream_id == video_id) { | ||
| 155 | + srs_freep(video_rtp); | ||
| 156 | + rtp = video_rtp = new SrsRtpConn(this, lpm); | ||
| 157 | + } else { | ||
| 158 | + srs_freep(audio_rtp); | ||
| 159 | + rtp = audio_rtp = new SrsRtpConn(this, lpm); | ||
| 160 | + } | ||
| 161 | + if ((ret = rtp->listen()) != ERROR_SUCCESS) { | ||
| 162 | + srs_error("rtsp: rtp listen at port=%d failed. ret=%d", lpm, ret); | ||
| 163 | + return ret; | ||
| 164 | + } | ||
| 165 | + srs_trace("rtsp: rtp listen at port=%d ok.", lpm); | ||
| 166 | + | ||
| 122 | SrsRtspSetupResponse* res = new SrsRtspSetupResponse(req->seq); | 167 | SrsRtspSetupResponse* res = new SrsRtspSetupResponse(req->seq); |
| 123 | res->client_port_min = req->transport->client_port_min; | 168 | res->client_port_min = req->transport->client_port_min; |
| 124 | res->client_port_max = req->transport->client_port_max; | 169 | res->client_port_max = req->transport->client_port_max; |
| 125 | - res->local_port_min = local_port_min; | ||
| 126 | - res->local_port_max = local_port_max; | 170 | + res->local_port_min = lpm; |
| 171 | + res->local_port_max = lpm + 1; | ||
| 127 | res->session = session; | 172 | res->session = session; |
| 128 | if ((ret = rtsp->send_message(res)) != ERROR_SUCCESS) { | 173 | if ((ret = rtsp->send_message(res)) != ERROR_SUCCESS) { |
| 129 | if (!srs_is_client_gracefully_close(ret)) { | 174 | if (!srs_is_client_gracefully_close(ret)) { |
| @@ -165,6 +210,14 @@ int SrsRtspConn::cycle() | @@ -165,6 +210,14 @@ int SrsRtspConn::cycle() | ||
| 165 | 210 | ||
| 166 | void SrsRtspConn::on_thread_stop() | 211 | void SrsRtspConn::on_thread_stop() |
| 167 | { | 212 | { |
| 213 | + if (video_rtp) { | ||
| 214 | + caster->free_port(video_rtp->port(), video_rtp->port() + 1); | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + if (audio_rtp) { | ||
| 218 | + caster->free_port(audio_rtp->port(), audio_rtp->port() + 1); | ||
| 219 | + } | ||
| 220 | + | ||
| 168 | caster->remove(this); | 221 | caster->remove(this); |
| 169 | } | 222 | } |
| 170 | 223 | ||
| @@ -184,16 +237,40 @@ SrsRtspCaster::~SrsRtspCaster() | @@ -184,16 +237,40 @@ SrsRtspCaster::~SrsRtspCaster() | ||
| 184 | srs_freep(conn); | 237 | srs_freep(conn); |
| 185 | } | 238 | } |
| 186 | clients.clear(); | 239 | clients.clear(); |
| 240 | + used_ports.clear(); | ||
| 241 | +} | ||
| 242 | + | ||
| 243 | +int SrsRtspCaster::alloc_port(int* pport) | ||
| 244 | +{ | ||
| 245 | + int ret = ERROR_SUCCESS; | ||
| 246 | + | ||
| 247 | + // use a pair of port. | ||
| 248 | + for (int i = local_port_min; i < local_port_max - 1; i += 2) { | ||
| 249 | + if (!used_ports[i]) { | ||
| 250 | + used_ports[i] = true; | ||
| 251 | + used_ports[i + 1] = true; | ||
| 252 | + *pport = i; | ||
| 253 | + break; | ||
| 254 | + } | ||
| 255 | + } | ||
| 256 | + srs_info("rtsp: alloc port=%d-%d", *pport, *pport + 1); | ||
| 257 | + | ||
| 258 | + return ret; | ||
| 259 | +} | ||
| 260 | + | ||
| 261 | +void SrsRtspCaster::free_port(int lpmin, int lpmax) | ||
| 262 | +{ | ||
| 263 | + for (int i = lpmin; i < lpmax; i++) { | ||
| 264 | + used_ports[i] = false; | ||
| 265 | + } | ||
| 266 | + srs_trace("rtsp: free rtp port=%d-%d", lpmin, lpmax); | ||
| 187 | } | 267 | } |
| 188 | 268 | ||
| 189 | -int SrsRtspCaster::serve_client(st_netfd_t stfd) | 269 | +int SrsRtspCaster::on_tcp_client(st_netfd_t stfd) |
| 190 | { | 270 | { |
| 191 | int ret = ERROR_SUCCESS; | 271 | int ret = ERROR_SUCCESS; |
| 192 | 272 | ||
| 193 | - SrsRtspConn* conn = new SrsRtspConn( | ||
| 194 | - this, stfd, | ||
| 195 | - output, local_port_min, local_port_max | ||
| 196 | - ); | 273 | + SrsRtspConn* conn = new SrsRtspConn(this, stfd, output); |
| 197 | 274 | ||
| 198 | if ((ret = conn->serve()) != ERROR_SUCCESS) { | 275 | if ((ret = conn->serve()) != ERROR_SUCCESS) { |
| 199 | srs_error("rtsp: serve client failed. ret=%d", ret); | 276 | srs_error("rtsp: serve client failed. ret=%d", ret); |
| @@ -32,30 +32,38 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -32,30 +32,38 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 32 | 32 | ||
| 33 | #include <string> | 33 | #include <string> |
| 34 | #include <vector> | 34 | #include <vector> |
| 35 | +#include <map> | ||
| 35 | 36 | ||
| 36 | #include <srs_app_st.hpp> | 37 | #include <srs_app_st.hpp> |
| 37 | #include <srs_app_thread.hpp> | 38 | #include <srs_app_thread.hpp> |
| 39 | +#include <srs_app_listener.hpp> | ||
| 38 | 40 | ||
| 39 | #ifdef SRS_AUTO_STREAM_CASTER | 41 | #ifdef SRS_AUTO_STREAM_CASTER |
| 40 | 42 | ||
| 41 | -class SrsConfDirective; | ||
| 42 | class SrsStSocket; | 43 | class SrsStSocket; |
| 44 | +class SrsRtspConn; | ||
| 43 | class SrsRtspStack; | 45 | class SrsRtspStack; |
| 44 | class SrsRtspCaster; | 46 | class SrsRtspCaster; |
| 47 | +class SrsConfDirective; | ||
| 45 | 48 | ||
| 46 | /** | 49 | /** |
| 47 | -* the handler for rtsp handler. | 50 | +* a rtp connection which transport a stream. |
| 48 | */ | 51 | */ |
| 49 | -class ISrsRtspHandler | 52 | +class SrsRtpConn: public ISrsUdpHandler |
| 50 | { | 53 | { |
| 54 | +private: | ||
| 55 | + SrsUdpListener* listener; | ||
| 56 | + SrsRtspConn* rtsp; | ||
| 57 | + int _port; | ||
| 51 | public: | 58 | public: |
| 52 | - ISrsRtspHandler(); | ||
| 53 | - virtual ~ISrsRtspHandler(); | 59 | + SrsRtpConn(SrsRtspConn* r, int p); |
| 60 | + virtual ~SrsRtpConn(); | ||
| 54 | public: | 61 | public: |
| 55 | - /** | ||
| 56 | - * serve the rtsp connection. | ||
| 57 | - */ | ||
| 58 | - virtual int serve_client(st_netfd_t stfd) = 0; | 62 | + virtual int port(); |
| 63 | + virtual int listen(); | ||
| 64 | +// interface ISrsUdpHandler | ||
| 65 | +public: | ||
| 66 | + virtual int on_udp_packet(sockaddr_in* from, char* buf, int nb_buf); | ||
| 59 | }; | 67 | }; |
| 60 | 68 | ||
| 61 | /** | 69 | /** |
| @@ -65,10 +73,14 @@ class SrsRtspConn : public ISrsThreadHandler | @@ -65,10 +73,14 @@ class SrsRtspConn : public ISrsThreadHandler | ||
| 65 | { | 73 | { |
| 66 | private: | 74 | private: |
| 67 | std::string output; | 75 | std::string output; |
| 68 | - int local_port_min; | ||
| 69 | - int local_port_max; | ||
| 70 | private: | 76 | private: |
| 71 | std::string session; | 77 | std::string session; |
| 78 | + // video stream. | ||
| 79 | + std::string video_id; | ||
| 80 | + SrsRtpConn* video_rtp; | ||
| 81 | + // audio stream. | ||
| 82 | + std::string audio_id; | ||
| 83 | + SrsRtpConn* audio_rtp; | ||
| 72 | // video sequence header. | 84 | // video sequence header. |
| 73 | std::string sps; | 85 | std::string sps; |
| 74 | std::string pps; | 86 | std::string pps; |
| @@ -81,7 +93,7 @@ private: | @@ -81,7 +93,7 @@ private: | ||
| 81 | SrsRtspCaster* caster; | 93 | SrsRtspCaster* caster; |
| 82 | SrsThread* trd; | 94 | SrsThread* trd; |
| 83 | public: | 95 | public: |
| 84 | - SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o, int lpmin, int lpmax); | 96 | + SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o); |
| 85 | virtual ~SrsRtspConn(); | 97 | virtual ~SrsRtspConn(); |
| 86 | public: | 98 | public: |
| 87 | virtual int serve(); | 99 | virtual int serve(); |
| @@ -96,19 +108,32 @@ public: | @@ -96,19 +108,32 @@ public: | ||
| 96 | /** | 108 | /** |
| 97 | * the caster for rtsp. | 109 | * the caster for rtsp. |
| 98 | */ | 110 | */ |
| 99 | -class SrsRtspCaster : public ISrsRtspHandler | 111 | +class SrsRtspCaster : public ISrsTcpHandler |
| 100 | { | 112 | { |
| 101 | private: | 113 | private: |
| 102 | std::string output; | 114 | std::string output; |
| 103 | int local_port_min; | 115 | int local_port_min; |
| 104 | int local_port_max; | 116 | int local_port_max; |
| 117 | + // key: port, value: whether used. | ||
| 118 | + std::map<int, bool> used_ports; | ||
| 105 | private: | 119 | private: |
| 106 | std::vector<SrsRtspConn*> clients; | 120 | std::vector<SrsRtspConn*> clients; |
| 107 | public: | 121 | public: |
| 108 | SrsRtspCaster(SrsConfDirective* c); | 122 | SrsRtspCaster(SrsConfDirective* c); |
| 109 | virtual ~SrsRtspCaster(); | 123 | virtual ~SrsRtspCaster(); |
| 110 | public: | 124 | public: |
| 111 | - virtual int serve_client(st_netfd_t stfd); | 125 | + /** |
| 126 | + * alloc a rtp port from local ports pool. | ||
| 127 | + * @param pport output the rtp port. | ||
| 128 | + */ | ||
| 129 | + virtual int alloc_port(int* pport); | ||
| 130 | + /** | ||
| 131 | + * free the alloced rtp port. | ||
| 132 | + */ | ||
| 133 | + virtual void free_port(int lpmin, int lpmax); | ||
| 134 | +// interface ISrsTcpHandler | ||
| 135 | +public: | ||
| 136 | + virtual int on_tcp_client(st_netfd_t stfd); | ||
| 112 | // internal methods. | 137 | // internal methods. |
| 113 | public: | 138 | public: |
| 114 | virtual void remove(SrsRtspConn* conn); | 139 | virtual void remove(SrsRtspConn* conn); |
| @@ -220,7 +220,7 @@ int SrsRtspListener::on_tcp_client(st_netfd_t stfd) | @@ -220,7 +220,7 @@ int SrsRtspListener::on_tcp_client(st_netfd_t stfd) | ||
| 220 | { | 220 | { |
| 221 | int ret = ERROR_SUCCESS; | 221 | int ret = ERROR_SUCCESS; |
| 222 | 222 | ||
| 223 | - if ((ret = caster->serve_client(stfd)) != ERROR_SUCCESS) { | 223 | + if ((ret = caster->on_tcp_client(stfd)) != ERROR_SUCCESS) { |
| 224 | srs_warn("accept client error. ret=%d", ret); | 224 | srs_warn("accept client error. ret=%d", ret); |
| 225 | return ret; | 225 | return ret; |
| 226 | } | 226 | } |
| @@ -47,8 +47,8 @@ class SrsIngester; | @@ -47,8 +47,8 @@ class SrsIngester; | ||
| 47 | class SrsHttpHeartbeat; | 47 | class SrsHttpHeartbeat; |
| 48 | class SrsKbps; | 48 | class SrsKbps; |
| 49 | class SrsConfDirective; | 49 | class SrsConfDirective; |
| 50 | +class ISrsTcpHandler; | ||
| 50 | class ISrsUdpHandler; | 51 | class ISrsUdpHandler; |
| 51 | -class ISrsRtspHandler; | ||
| 52 | class SrsUdpListener; | 52 | class SrsUdpListener; |
| 53 | class SrsTcpListener; | 53 | class SrsTcpListener; |
| 54 | 54 | ||
| @@ -111,8 +111,7 @@ class SrsRtspListener : virtual public SrsListener, virtual public ISrsTcpHandle | @@ -111,8 +111,7 @@ class SrsRtspListener : virtual public SrsListener, virtual public ISrsTcpHandle | ||
| 111 | { | 111 | { |
| 112 | private: | 112 | private: |
| 113 | SrsTcpListener* listener; | 113 | SrsTcpListener* listener; |
| 114 | -private: | ||
| 115 | - ISrsRtspHandler* caster; | 114 | + ISrsTcpHandler* caster; |
| 116 | public: | 115 | public: |
| 117 | SrsRtspListener(SrsServer* server, SrsListenerType type, SrsConfDirective* c); | 116 | SrsRtspListener(SrsServer* server, SrsListenerType type, SrsConfDirective* c); |
| 118 | virtual ~SrsRtspListener(); | 117 | virtual ~SrsRtspListener(); |
| @@ -62,6 +62,7 @@ SrsThread::SrsThread(const char* name, ISrsThreadHandler* thread_handler, int64_ | @@ -62,6 +62,7 @@ SrsThread::SrsThread(const char* name, ISrsThreadHandler* thread_handler, int64_ | ||
| 62 | 62 | ||
| 63 | tid = NULL; | 63 | tid = NULL; |
| 64 | loop = false; | 64 | loop = false; |
| 65 | + really_terminated = true; | ||
| 65 | _cid = -1; | 66 | _cid = -1; |
| 66 | _joinable = joinable; | 67 | _joinable = joinable; |
| 67 | 68 | ||
| @@ -120,10 +121,27 @@ void SrsThread::stop() | @@ -120,10 +121,27 @@ void SrsThread::stop() | ||
| 120 | // which will terminate the cycle thread. | 121 | // which will terminate the cycle thread. |
| 121 | st_thread_interrupt(tid); | 122 | st_thread_interrupt(tid); |
| 122 | 123 | ||
| 123 | - // wait the thread to exit. | ||
| 124 | - int ret = st_thread_join(tid, NULL); | ||
| 125 | - // TODO: FIXME: the join maybe failed, should use a variable to ensure thread terminated. | ||
| 126 | - srs_assert(ret == 0); | 124 | + // when joinable, wait util quit. |
| 125 | + if (_joinable) { | ||
| 126 | + // wait the thread to exit. | ||
| 127 | + int ret = st_thread_join(tid, NULL); | ||
| 128 | + if (ret) { | ||
| 129 | + srs_warn("core: ignore join thread failed."); | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + // wait the thread actually terminated. | ||
| 133 | + // sometimes the thread join return -1, for example, | ||
| 134 | + // when thread use st_recvfrom, the thread join return -1. | ||
| 135 | + // so here, we use a variable to ensure the thread stopped. | ||
| 136 | + while (!really_terminated) { | ||
| 137 | + st_usleep(10 * 1000); | ||
| 138 | + | ||
| 139 | + if (really_terminated) { | ||
| 140 | + break; | ||
| 141 | + } | ||
| 142 | + srs_warn("core: wait thread to actually terminated"); | ||
| 143 | + } | ||
| 144 | + } | ||
| 127 | 145 | ||
| 128 | tid = NULL; | 146 | tid = NULL; |
| 129 | } | 147 | } |
| @@ -150,6 +168,9 @@ void SrsThread::thread_cycle() | @@ -150,6 +168,9 @@ void SrsThread::thread_cycle() | ||
| 150 | 168 | ||
| 151 | srs_assert(handler); | 169 | srs_assert(handler); |
| 152 | handler->on_thread_start(); | 170 | handler->on_thread_start(); |
| 171 | + | ||
| 172 | + // thread is running now. | ||
| 173 | + really_terminated = false; | ||
| 153 | 174 | ||
| 154 | // wait for cid to ready, for parent thread to get the cid. | 175 | // wait for cid to ready, for parent thread to get the cid. |
| 155 | while (!can_run && loop) { | 176 | while (!can_run && loop) { |
| @@ -191,6 +212,9 @@ failed: | @@ -191,6 +212,9 @@ failed: | ||
| 191 | 212 | ||
| 192 | handler->on_thread_stop(); | 213 | handler->on_thread_stop(); |
| 193 | srs_info("thread %s cycle finished", _name); | 214 | srs_info("thread %s cycle finished", _name); |
| 215 | + | ||
| 216 | + // readly terminated now. | ||
| 217 | + really_terminated = true; | ||
| 194 | } | 218 | } |
| 195 | 219 | ||
| 196 | void* SrsThread::thread_fun(void* arg) | 220 | void* SrsThread::thread_fun(void* arg) |
| @@ -746,6 +746,18 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req) | @@ -746,6 +746,18 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req) | ||
| 746 | } | 746 | } |
| 747 | } | 747 | } |
| 748 | 748 | ||
| 749 | + // for setup, parse the stream id from uri. | ||
| 750 | + if (req->is_setup()) { | ||
| 751 | + size_t pos = string::npos; | ||
| 752 | + if ((pos = req->uri.rfind("/")) != string::npos) { | ||
| 753 | + req->stream_id = req->uri.substr(pos + 1); | ||
| 754 | + } | ||
| 755 | + if ((pos = req->stream_id.find("=")) != string::npos) { | ||
| 756 | + req->stream_id = req->stream_id.substr(pos + 1); | ||
| 757 | + } | ||
| 758 | + srs_info("rtsp: setup stream id=%s", req->stream_id.c_str()); | ||
| 759 | + } | ||
| 760 | + | ||
| 749 | // parse rdp body. | 761 | // parse rdp body. |
| 750 | long consumed = 0; | 762 | long consumed = 0; |
| 751 | while (consumed < req->content_length) { | 763 | while (consumed < req->content_length) { |
| @@ -337,6 +337,7 @@ public: | @@ -337,6 +337,7 @@ public: | ||
| 337 | * assumed. It is interpreted according to [H14.14]. | 337 | * assumed. It is interpreted according to [H14.14]. |
| 338 | */ | 338 | */ |
| 339 | long content_length; | 339 | long content_length; |
| 340 | + | ||
| 340 | /** | 341 | /** |
| 341 | * the sdp in announce, NULL for no sdp. | 342 | * the sdp in announce, NULL for no sdp. |
| 342 | */ | 343 | */ |
| @@ -345,6 +346,10 @@ public: | @@ -345,6 +346,10 @@ public: | ||
| 345 | * the transport in setup, NULL for no transport. | 346 | * the transport in setup, NULL for no transport. |
| 346 | */ | 347 | */ |
| 347 | SrsRtspTransport* transport; | 348 | SrsRtspTransport* transport; |
| 349 | + /** | ||
| 350 | + * for setup message, parse the stream id from uri. | ||
| 351 | + */ | ||
| 352 | + std::string stream_id; | ||
| 348 | public: | 353 | public: |
| 349 | SrsRtspRequest(); | 354 | SrsRtspRequest(); |
| 350 | virtual ~SrsRtspRequest(); | 355 | virtual ~SrsRtspRequest(); |
-
请 注册 或 登录 后发表评论