正在显示
17 个修改的文件
包含
405 行增加
和
58 行删除
| @@ -893,20 +893,23 @@ vhost refer.anti_suck.com { | @@ -893,20 +893,23 @@ vhost refer.anti_suck.com { | ||
| 893 | pithy_print { | 893 | pithy_print { |
| 894 | # shared print interval for all publish clients, in milliseconds. | 894 | # shared print interval for all publish clients, in milliseconds. |
| 895 | # if not specified, set to 1100. | 895 | # if not specified, set to 1100. |
| 896 | - publish 2000; | 896 | + publish 10000; |
| 897 | # shared print interval for all play clients, in milliseconds. | 897 | # shared print interval for all play clients, in milliseconds. |
| 898 | # if not specified, set to 1300. | 898 | # if not specified, set to 1300. |
| 899 | - play 3000; | 899 | + play 10000; |
| 900 | # shared print interval for all forwarders, in milliseconds. | 900 | # shared print interval for all forwarders, in milliseconds. |
| 901 | # if not specified, set to 2000. | 901 | # if not specified, set to 2000. |
| 902 | - forwarder 3000; | 902 | + forwarder 10000; |
| 903 | # shared print interval for all encoders, in milliseconds. | 903 | # shared print interval for all encoders, in milliseconds. |
| 904 | # if not specified, set to 2000. | 904 | # if not specified, set to 2000. |
| 905 | - encoder 3000; | 905 | + encoder 10000; |
| 906 | # shared print interval for all ingesters, in milliseconds. | 906 | # shared print interval for all ingesters, in milliseconds. |
| 907 | # if not specified, set to 2000. | 907 | # if not specified, set to 2000. |
| 908 | - ingester 3000; | 908 | + ingester 10000; |
| 909 | # shared print interval for all hls, in milliseconds. | 909 | # shared print interval for all hls, in milliseconds. |
| 910 | # if not specified, set to 2000. | 910 | # if not specified, set to 2000. |
| 911 | - hls 3000; | 911 | + hls 10000; |
| 912 | + # shared print interval for all edge, in milliseconds. | ||
| 913 | + # if not specified, set to 2000. | ||
| 914 | + edge 10000; | ||
| 912 | } | 915 | } |
| @@ -1396,6 +1396,21 @@ int SrsConfig::get_pithy_print_play() | @@ -1396,6 +1396,21 @@ int SrsConfig::get_pithy_print_play() | ||
| 1396 | return ::atoi(pithy->arg0().c_str()); | 1396 | return ::atoi(pithy->arg0().c_str()); |
| 1397 | } | 1397 | } |
| 1398 | 1398 | ||
| 1399 | +int SrsConfig::get_pithy_print_edge() | ||
| 1400 | +{ | ||
| 1401 | + SrsConfDirective* pithy = root->get("pithy_print"); | ||
| 1402 | + if (!pithy) { | ||
| 1403 | + return SRS_STAGE_EDGE_INTERVAL_MS; | ||
| 1404 | + } | ||
| 1405 | + | ||
| 1406 | + pithy = pithy->get("edge"); | ||
| 1407 | + if (!pithy) { | ||
| 1408 | + return SRS_STAGE_EDGE_INTERVAL_MS; | ||
| 1409 | + } | ||
| 1410 | + | ||
| 1411 | + return ::atoi(pithy->arg0().c_str()); | ||
| 1412 | +} | ||
| 1413 | + | ||
| 1399 | SrsConfDirective* SrsConfig::get_vhost(string vhost) | 1414 | SrsConfDirective* SrsConfig::get_vhost(string vhost) |
| 1400 | { | 1415 | { |
| 1401 | srs_assert(root); | 1416 | srs_assert(root); |
| @@ -1821,6 +1836,17 @@ bool SrsConfig::get_vhost_is_edge(std::string vhost) | @@ -1821,6 +1836,17 @@ bool SrsConfig::get_vhost_is_edge(std::string vhost) | ||
| 1821 | return true; | 1836 | return true; |
| 1822 | } | 1837 | } |
| 1823 | 1838 | ||
| 1839 | +SrsConfDirective* SrsConfig::get_vhost_edge_origin(string vhost) | ||
| 1840 | +{ | ||
| 1841 | + SrsConfDirective* conf = get_vhost(vhost); | ||
| 1842 | + | ||
| 1843 | + if (!conf) { | ||
| 1844 | + return NULL; | ||
| 1845 | + } | ||
| 1846 | + | ||
| 1847 | + return conf->get("origin"); | ||
| 1848 | +} | ||
| 1849 | + | ||
| 1824 | SrsConfDirective* SrsConfig::get_transcode(string vhost, string scope) | 1850 | SrsConfDirective* SrsConfig::get_transcode(string vhost, string scope) |
| 1825 | { | 1851 | { |
| 1826 | SrsConfDirective* conf = get_vhost(vhost); | 1852 | SrsConfDirective* conf = get_vhost(vhost); |
| @@ -76,6 +76,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -76,6 +76,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 76 | #define SRS_STAGE_ENCODER_INTERVAL_MS 2000 | 76 | #define SRS_STAGE_ENCODER_INTERVAL_MS 2000 |
| 77 | #define SRS_STAGE_INGESTER_INTERVAL_MS 2000 | 77 | #define SRS_STAGE_INGESTER_INTERVAL_MS 2000 |
| 78 | #define SRS_STAGE_HLS_INTERVAL_MS 2000 | 78 | #define SRS_STAGE_HLS_INTERVAL_MS 2000 |
| 79 | +#define SRS_STAGE_EDGE_INTERVAL_MS 2000 | ||
| 79 | 80 | ||
| 80 | #define SRS_AUTO_INGEST_TYPE_FILE "file" | 81 | #define SRS_AUTO_INGEST_TYPE_FILE "file" |
| 81 | #define SRS_AUTO_INGEST_TYPE_STREAM "stream" | 82 | #define SRS_AUTO_INGEST_TYPE_STREAM "stream" |
| @@ -163,6 +164,7 @@ public: | @@ -163,6 +164,7 @@ public: | ||
| 163 | virtual int get_pithy_print_ingester(); | 164 | virtual int get_pithy_print_ingester(); |
| 164 | virtual int get_pithy_print_hls(); | 165 | virtual int get_pithy_print_hls(); |
| 165 | virtual int get_pithy_print_play(); | 166 | virtual int get_pithy_print_play(); |
| 167 | + virtual int get_pithy_print_edge(); | ||
| 166 | // vhost specified section | 168 | // vhost specified section |
| 167 | public: | 169 | public: |
| 168 | virtual SrsConfDirective* get_vhost(std::string vhost); | 170 | virtual SrsConfDirective* get_vhost(std::string vhost); |
| @@ -193,6 +195,7 @@ public: | @@ -193,6 +195,7 @@ public: | ||
| 193 | // vhost edge section | 195 | // vhost edge section |
| 194 | public: | 196 | public: |
| 195 | virtual bool get_vhost_is_edge(std::string vhost); | 197 | virtual bool get_vhost_is_edge(std::string vhost); |
| 198 | + virtual SrsConfDirective* get_vhost_edge_origin(std::string vhost); | ||
| 196 | // vhost transcode section | 199 | // vhost transcode section |
| 197 | public: | 200 | public: |
| 198 | virtual SrsConfDirective* get_transcode(std::string vhost, std::string scope); | 201 | virtual SrsConfDirective* get_transcode(std::string vhost, std::string scope); |
| @@ -23,28 +23,55 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -23,28 +23,55 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 23 | 23 | ||
| 24 | #include <srs_app_edge.hpp> | 24 | #include <srs_app_edge.hpp> |
| 25 | 25 | ||
| 26 | +#include <stdlib.h> | ||
| 27 | +#include <sys/socket.h> | ||
| 28 | +#include <netinet/in.h> | ||
| 29 | +#include <arpa/inet.h> | ||
| 30 | + | ||
| 26 | #include <srs_kernel_error.hpp> | 31 | #include <srs_kernel_error.hpp> |
| 27 | #include <srs_protocol_rtmp.hpp> | 32 | #include <srs_protocol_rtmp.hpp> |
| 28 | #include <srs_kernel_log.hpp> | 33 | #include <srs_kernel_log.hpp> |
| 34 | +#include <srs_protocol_rtmp.hpp> | ||
| 35 | +#include <srs_protocol_io.hpp> | ||
| 36 | +#include <srs_app_config.hpp> | ||
| 37 | +#include <srs_protocol_utility.hpp> | ||
| 38 | +#include <srs_protocol_rtmp.hpp> | ||
| 39 | +#include <srs_app_socket.hpp> | ||
| 40 | +#include <srs_protocol_rtmp_stack.hpp> | ||
| 41 | +#include <srs_app_source.hpp> | ||
| 42 | +#include <srs_app_pithy_print.hpp> | ||
| 43 | +#include <srs_core_autofree.hpp> | ||
| 29 | 44 | ||
| 30 | // when error, edge ingester sleep for a while and retry. | 45 | // when error, edge ingester sleep for a while and retry. |
| 31 | -#define SRS_EDGE_INGESTER_SLEEP_US (int64_t)(3*1000*1000LL) | 46 | +#define SRS_EDGE_INGESTER_SLEEP_US (int64_t)(1*1000*1000LL) |
| 47 | + | ||
| 48 | +// when edge timeout, retry next. | ||
| 49 | +#define SRS_EDGE_TIMEOUT_US (int64_t)(3*1000*1000LL) | ||
| 32 | 50 | ||
| 33 | SrsEdgeIngester::SrsEdgeIngester() | 51 | SrsEdgeIngester::SrsEdgeIngester() |
| 34 | { | 52 | { |
| 53 | + io = NULL; | ||
| 54 | + client = NULL; | ||
| 35 | _edge = NULL; | 55 | _edge = NULL; |
| 36 | _req = NULL; | 56 | _req = NULL; |
| 57 | + origin_index = 0; | ||
| 58 | + stream_id = 0; | ||
| 59 | + stfd = NULL; | ||
| 37 | pthread = new SrsThread(this, SRS_EDGE_INGESTER_SLEEP_US); | 60 | pthread = new SrsThread(this, SRS_EDGE_INGESTER_SLEEP_US); |
| 38 | } | 61 | } |
| 39 | 62 | ||
| 40 | SrsEdgeIngester::~SrsEdgeIngester() | 63 | SrsEdgeIngester::~SrsEdgeIngester() |
| 41 | { | 64 | { |
| 65 | + stop(); | ||
| 66 | + | ||
| 67 | + srs_freep(pthread); | ||
| 42 | } | 68 | } |
| 43 | 69 | ||
| 44 | -int SrsEdgeIngester::initialize(SrsEdge* edge, SrsRequest* req) | 70 | +int SrsEdgeIngester::initialize(SrsSource* source, SrsEdge* edge, SrsRequest* req) |
| 45 | { | 71 | { |
| 46 | int ret = ERROR_SUCCESS; | 72 | int ret = ERROR_SUCCESS; |
| 47 | 73 | ||
| 74 | + _source = source; | ||
| 48 | _edge = edge; | 75 | _edge = edge; |
| 49 | _req = req; | 76 | _req = req; |
| 50 | 77 | ||
| @@ -53,14 +80,229 @@ int SrsEdgeIngester::initialize(SrsEdge* edge, SrsRequest* req) | @@ -53,14 +80,229 @@ int SrsEdgeIngester::initialize(SrsEdge* edge, SrsRequest* req) | ||
| 53 | 80 | ||
| 54 | int SrsEdgeIngester::start() | 81 | int SrsEdgeIngester::start() |
| 55 | { | 82 | { |
| 83 | + return pthread->start(); | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +void SrsEdgeIngester::stop() | ||
| 87 | +{ | ||
| 88 | + pthread->stop(); | ||
| 89 | + | ||
| 90 | + close_underlayer_socket(); | ||
| 91 | + | ||
| 92 | + srs_freep(client); | ||
| 93 | + srs_freep(io); | ||
| 94 | +} | ||
| 95 | + | ||
| 96 | +int SrsEdgeIngester::cycle() | ||
| 97 | +{ | ||
| 56 | int ret = ERROR_SUCCESS; | 98 | int ret = ERROR_SUCCESS; |
| 99 | + | ||
| 100 | + if ((ret = connect_server()) != ERROR_SUCCESS) { | ||
| 101 | + return ret; | ||
| 102 | + } | ||
| 103 | + srs_assert(client); | ||
| 104 | + | ||
| 105 | + client->set_recv_timeout(SRS_RECV_TIMEOUT_US); | ||
| 106 | + client->set_send_timeout(SRS_SEND_TIMEOUT_US); | ||
| 107 | + | ||
| 108 | + SrsRequest* req = _req; | ||
| 109 | + | ||
| 110 | + if ((ret = client->handshake()) != ERROR_SUCCESS) { | ||
| 111 | + srs_error("handshake with server failed. ret=%d", ret); | ||
| 112 | + return ret; | ||
| 113 | + } | ||
| 114 | + if ((ret = client->connect_app(req->app, req->tcUrl)) != ERROR_SUCCESS) { | ||
| 115 | + srs_error("connect with server failed, tcUrl=%s. ret=%d", req->tcUrl.c_str(), ret); | ||
| 116 | + return ret; | ||
| 117 | + } | ||
| 118 | + if ((ret = client->create_stream(stream_id)) != ERROR_SUCCESS) { | ||
| 119 | + srs_error("connect with server failed, stream_id=%d. ret=%d", stream_id, ret); | ||
| 120 | + return ret; | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + if ((ret = client->play(req->stream, stream_id)) != ERROR_SUCCESS) { | ||
| 124 | + srs_error("connect with server failed, stream=%s, stream_id=%d. ret=%d", | ||
| 125 | + req->stream.c_str(), stream_id, ret); | ||
| 126 | + return ret; | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + if ((ret = _source->on_publish()) != ERROR_SUCCESS) { | ||
| 130 | + srs_error("edge ingester play stream then publish to edge failed. ret=%d", ret); | ||
| 131 | + return ret; | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + if ((ret = _edge->on_ingest_play()) != ERROR_SUCCESS) { | ||
| 135 | + return ret; | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + if ((ret = ingest()) != ERROR_SUCCESS) { | ||
| 139 | + return ret; | ||
| 140 | + } | ||
| 141 | + | ||
| 57 | return ret; | 142 | return ret; |
| 58 | - //return pthread->start(); | ||
| 59 | } | 143 | } |
| 60 | 144 | ||
| 61 | -int SrsEdgeIngester::cycle() | 145 | +int SrsEdgeIngester::ingest() |
| 62 | { | 146 | { |
| 63 | int ret = ERROR_SUCCESS; | 147 | int ret = ERROR_SUCCESS; |
| 148 | + | ||
| 149 | + client->set_recv_timeout(SRS_EDGE_TIMEOUT_US); | ||
| 150 | + | ||
| 151 | + SrsPithyPrint pithy_print(SRS_STAGE_EDGE); | ||
| 152 | + | ||
| 153 | + while (pthread->can_loop()) { | ||
| 154 | + // switch to other st-threads. | ||
| 155 | + st_usleep(0); | ||
| 156 | + | ||
| 157 | + pithy_print.elapse(); | ||
| 158 | + | ||
| 159 | + // pithy print | ||
| 160 | + if (pithy_print.can_print()) { | ||
| 161 | + srs_trace("<- time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", | ||
| 162 | + pithy_print.age(), client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps()); | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + // read from client. | ||
| 166 | + SrsCommonMessage* msg = NULL; | ||
| 167 | + if ((ret = client->recv_message(&msg)) != ERROR_SUCCESS) { | ||
| 168 | + srs_error("recv origin server message failed. ret=%d", ret); | ||
| 169 | + return ret; | ||
| 170 | + } | ||
| 171 | + srs_verbose("edge loop recv message. ret=%d", ret); | ||
| 172 | + | ||
| 173 | + srs_assert(msg); | ||
| 174 | + SrsAutoFree(SrsCommonMessage, msg, false); | ||
| 175 | + | ||
| 176 | + if ((ret = process_publish_message(msg)) != ERROR_SUCCESS) { | ||
| 177 | + return ret; | ||
| 178 | + } | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + return ret; | ||
| 182 | +} | ||
| 183 | + | ||
| 184 | +int SrsEdgeIngester::process_publish_message(SrsCommonMessage* msg) | ||
| 185 | +{ | ||
| 186 | + int ret = ERROR_SUCCESS; | ||
| 187 | + | ||
| 188 | + SrsSource* source = _source; | ||
| 189 | + | ||
| 190 | + // process audio packet | ||
| 191 | + if (msg->header.is_audio()) { | ||
| 192 | + if ((ret = source->on_audio(msg)) != ERROR_SUCCESS) { | ||
| 193 | + srs_error("source process audio message failed. ret=%d", ret); | ||
| 194 | + return ret; | ||
| 195 | + } | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + // process video packet | ||
| 199 | + if (msg->header.is_video()) { | ||
| 200 | + if ((ret = source->on_video(msg)) != ERROR_SUCCESS) { | ||
| 201 | + srs_error("source process video message failed. ret=%d", ret); | ||
| 202 | + return ret; | ||
| 203 | + } | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + // process onMetaData | ||
| 207 | + if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) { | ||
| 208 | + if ((ret = msg->decode_packet(client->get_protocol())) != ERROR_SUCCESS) { | ||
| 209 | + srs_error("decode onMetaData message failed. ret=%d", ret); | ||
| 210 | + return ret; | ||
| 211 | + } | ||
| 212 | + | ||
| 213 | + SrsPacket* pkt = msg->get_packet(); | ||
| 214 | + if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) { | ||
| 215 | + SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt); | ||
| 216 | + if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) { | ||
| 217 | + srs_error("source process onMetaData message failed. ret=%d", ret); | ||
| 218 | + return ret; | ||
| 219 | + } | ||
| 220 | + srs_trace("process onMetaData message success."); | ||
| 221 | + return ret; | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + srs_trace("ignore AMF0/AMF3 data message."); | ||
| 225 | + return ret; | ||
| 226 | + } | ||
| 227 | + | ||
| 228 | + return ret; | ||
| 229 | +} | ||
| 230 | + | ||
| 231 | +void SrsEdgeIngester::close_underlayer_socket() | ||
| 232 | +{ | ||
| 233 | + srs_close_stfd(stfd); | ||
| 234 | +} | ||
| 235 | + | ||
| 236 | +int SrsEdgeIngester::connect_server() | ||
| 237 | +{ | ||
| 238 | + int ret = ERROR_SUCCESS; | ||
| 239 | + | ||
| 240 | + // reopen | ||
| 241 | + close_underlayer_socket(); | ||
| 242 | + | ||
| 243 | + // TODO: FIXME: support reload | ||
| 244 | + SrsConfDirective* conf = _srs_config->get_vhost_edge_origin(_req->vhost); | ||
| 245 | + srs_assert(conf); | ||
| 246 | + | ||
| 247 | + // select the origin. | ||
| 248 | + std::string server = conf->args.at(origin_index % conf->args.size()); | ||
| 249 | + origin_index = (origin_index + 1) % conf->args.size(); | ||
| 250 | + | ||
| 251 | + std::string s_port = RTMP_DEFAULT_PORT; | ||
| 252 | + int port = ::atoi(RTMP_DEFAULT_PORT); | ||
| 253 | + size_t pos = server.find(":"); | ||
| 254 | + if (pos != std::string::npos) { | ||
| 255 | + s_port = server.substr(pos + 1); | ||
| 256 | + server = server.substr(0, pos); | ||
| 257 | + port = ::atoi(s_port.c_str()); | ||
| 258 | + } | ||
| 259 | + | ||
| 260 | + // open socket. | ||
| 261 | + srs_trace("connect edge stream=%s, tcUrl=%s to server=%s, port=%d", | ||
| 262 | + _req->stream.c_str(), _req->tcUrl.c_str(), server.c_str(), port); | ||
| 263 | + | ||
| 264 | + // TODO: FIXME: extract utility method | ||
| 265 | + int sock = socket(AF_INET, SOCK_STREAM, 0); | ||
| 266 | + if(sock == -1){ | ||
| 267 | + ret = ERROR_SOCKET_CREATE; | ||
| 268 | + srs_error("create socket error. ret=%d", ret); | ||
| 269 | + return ret; | ||
| 270 | + } | ||
| 271 | + | ||
| 272 | + srs_assert(!stfd); | ||
| 273 | + stfd = st_netfd_open_socket(sock); | ||
| 274 | + if(stfd == NULL){ | ||
| 275 | + ret = ERROR_ST_OPEN_SOCKET; | ||
| 276 | + srs_error("st_netfd_open_socket failed. ret=%d", ret); | ||
| 277 | + return ret; | ||
| 278 | + } | ||
| 279 | + | ||
| 280 | + srs_freep(client); | ||
| 281 | + srs_freep(io); | ||
| 282 | + | ||
| 283 | + io = new SrsSocket(stfd); | ||
| 284 | + client = new SrsRtmpClient(io); | ||
| 285 | + | ||
| 286 | + // connect to server. | ||
| 287 | + std::string ip = srs_dns_resolve(server); | ||
| 288 | + if (ip.empty()) { | ||
| 289 | + ret = ERROR_SYSTEM_IP_INVALID; | ||
| 290 | + srs_error("dns resolve server error, ip empty. ret=%d", ret); | ||
| 291 | + return ret; | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + sockaddr_in addr; | ||
| 295 | + addr.sin_family = AF_INET; | ||
| 296 | + addr.sin_port = htons(port); | ||
| 297 | + addr.sin_addr.s_addr = inet_addr(ip.c_str()); | ||
| 298 | + | ||
| 299 | + if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){ | ||
| 300 | + ret = ERROR_ST_CONNECT; | ||
| 301 | + srs_error("connect to server error. ip=%s, port=%d, ret=%d", ip.c_str(), port, ret); | ||
| 302 | + return ret; | ||
| 303 | + } | ||
| 304 | + srs_trace("connect to server success. server=%s, ip=%s, port=%d", server.c_str(), ip.c_str(), port); | ||
| 305 | + | ||
| 64 | return ret; | 306 | return ret; |
| 65 | } | 307 | } |
| 66 | 308 | ||
| @@ -75,11 +317,11 @@ SrsEdge::~SrsEdge() | @@ -75,11 +317,11 @@ SrsEdge::~SrsEdge() | ||
| 75 | srs_freep(ingester); | 317 | srs_freep(ingester); |
| 76 | } | 318 | } |
| 77 | 319 | ||
| 78 | -int SrsEdge::initialize(SrsRequest* req) | 320 | +int SrsEdge::initialize(SrsSource* source, SrsRequest* req) |
| 79 | { | 321 | { |
| 80 | int ret = ERROR_SUCCESS; | 322 | int ret = ERROR_SUCCESS; |
| 81 | 323 | ||
| 82 | - if ((ret = ingester->initialize(this, req)) != ERROR_SUCCESS) { | 324 | + if ((ret = ingester->initialize(source, this, req)) != ERROR_SUCCESS) { |
| 83 | return ret; | 325 | return ret; |
| 84 | } | 326 | } |
| 85 | 327 | ||
| @@ -106,3 +348,25 @@ int SrsEdge::on_client_play() | @@ -106,3 +348,25 @@ int SrsEdge::on_client_play() | ||
| 106 | return ret; | 348 | return ret; |
| 107 | } | 349 | } |
| 108 | 350 | ||
| 351 | +void SrsEdge::on_all_client_stop() | ||
| 352 | +{ | ||
| 353 | + if (state == SrsEdgeStateIngestConnected) { | ||
| 354 | + ingester->stop(); | ||
| 355 | + } | ||
| 356 | + | ||
| 357 | + SrsEdgeState pstate = state; | ||
| 358 | + state = SrsEdgeStateInit; | ||
| 359 | + srs_trace("edge change from %d to state %d (init).", pstate, state); | ||
| 360 | +} | ||
| 361 | + | ||
| 362 | +int SrsEdge::on_ingest_play() | ||
| 363 | +{ | ||
| 364 | + int ret = ERROR_SUCCESS; | ||
| 365 | + | ||
| 366 | + SrsEdgeState pstate = state; | ||
| 367 | + state = SrsEdgeStateIngestConnected; | ||
| 368 | + | ||
| 369 | + srs_trace("edge change from %d to state %d (ingest connected).", pstate, state); | ||
| 370 | + | ||
| 371 | + return ret; | ||
| 372 | +} |
| @@ -30,10 +30,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -30,10 +30,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 30 | 30 | ||
| 31 | #include <srs_core.hpp> | 31 | #include <srs_core.hpp> |
| 32 | 32 | ||
| 33 | +#include <srs_app_st.hpp> | ||
| 33 | #include <srs_app_thread.hpp> | 34 | #include <srs_app_thread.hpp> |
| 34 | 35 | ||
| 35 | class SrsEdge; | 36 | class SrsEdge; |
| 37 | +class SrsSource; | ||
| 36 | class SrsRequest; | 38 | class SrsRequest; |
| 39 | +class SrsRtmpClient; | ||
| 40 | +class SrsCommonMessage; | ||
| 41 | +class ISrsProtocolReaderWriter; | ||
| 37 | 42 | ||
| 38 | /** | 43 | /** |
| 39 | * the state of edge | 44 | * the state of edge |
| @@ -43,7 +48,10 @@ enum SrsEdgeState | @@ -43,7 +48,10 @@ enum SrsEdgeState | ||
| 43 | SrsEdgeStateInit = 0, | 48 | SrsEdgeStateInit = 0, |
| 44 | SrsEdgeStatePlay = 100, | 49 | SrsEdgeStatePlay = 100, |
| 45 | SrsEdgeStatePublish, | 50 | SrsEdgeStatePublish, |
| 46 | - SrsEdgeStateConnected, | 51 | + // play stream from origin, ingest stream |
| 52 | + SrsEdgeStateIngestConnected, | ||
| 53 | + // publish stream to edge, forward to origin | ||
| 54 | + SrsEdgeStateForwardConnected, | ||
| 47 | SrsEdgeStateAborting, | 55 | SrsEdgeStateAborting, |
| 48 | SrsEdgeStateReloading, | 56 | SrsEdgeStateReloading, |
| 49 | }; | 57 | }; |
| @@ -54,18 +62,31 @@ enum SrsEdgeState | @@ -54,18 +62,31 @@ enum SrsEdgeState | ||
| 54 | class SrsEdgeIngester : public ISrsThreadHandler | 62 | class SrsEdgeIngester : public ISrsThreadHandler |
| 55 | { | 63 | { |
| 56 | private: | 64 | private: |
| 65 | + int stream_id; | ||
| 66 | +private: | ||
| 67 | + SrsSource* _source; | ||
| 57 | SrsEdge* _edge; | 68 | SrsEdge* _edge; |
| 58 | SrsRequest* _req; | 69 | SrsRequest* _req; |
| 59 | SrsThread* pthread; | 70 | SrsThread* pthread; |
| 71 | + st_netfd_t stfd; | ||
| 72 | + ISrsProtocolReaderWriter* io; | ||
| 73 | + SrsRtmpClient* client; | ||
| 74 | + int origin_index; | ||
| 60 | public: | 75 | public: |
| 61 | SrsEdgeIngester(); | 76 | SrsEdgeIngester(); |
| 62 | virtual ~SrsEdgeIngester(); | 77 | virtual ~SrsEdgeIngester(); |
| 63 | public: | 78 | public: |
| 64 | - virtual int initialize(SrsEdge* edge, SrsRequest* req); | 79 | + virtual int initialize(SrsSource* source, SrsEdge* edge, SrsRequest* req); |
| 65 | virtual int start(); | 80 | virtual int start(); |
| 81 | + virtual void stop(); | ||
| 66 | // interface ISrsThreadHandler | 82 | // interface ISrsThreadHandler |
| 67 | public: | 83 | public: |
| 68 | virtual int cycle(); | 84 | virtual int cycle(); |
| 85 | +private: | ||
| 86 | + virtual int ingest(); | ||
| 87 | + virtual void close_underlayer_socket(); | ||
| 88 | + virtual int connect_server(); | ||
| 89 | + virtual int process_publish_message(SrsCommonMessage* msg); | ||
| 69 | }; | 90 | }; |
| 70 | 91 | ||
| 71 | /** | 92 | /** |
| @@ -80,11 +101,20 @@ public: | @@ -80,11 +101,20 @@ public: | ||
| 80 | SrsEdge(); | 101 | SrsEdge(); |
| 81 | virtual ~SrsEdge(); | 102 | virtual ~SrsEdge(); |
| 82 | public: | 103 | public: |
| 83 | - virtual int initialize(SrsRequest* req); | 104 | + virtual int initialize(SrsSource* source, SrsRequest* req); |
| 84 | /** | 105 | /** |
| 85 | * when client play stream on edge. | 106 | * when client play stream on edge. |
| 86 | */ | 107 | */ |
| 87 | virtual int on_client_play(); | 108 | virtual int on_client_play(); |
| 109 | + /** | ||
| 110 | + * when all client stopped play, disconnect to origin. | ||
| 111 | + */ | ||
| 112 | + virtual void on_all_client_stop(); | ||
| 113 | +public: | ||
| 114 | + /** | ||
| 115 | + * when ingester start to play stream. | ||
| 116 | + */ | ||
| 117 | + virtual int on_ingest_play(); | ||
| 88 | }; | 118 | }; |
| 89 | 119 | ||
| 90 | #endif | 120 | #endif |
| @@ -113,7 +113,7 @@ int SrsEncoder::cycle() | @@ -113,7 +113,7 @@ int SrsEncoder::cycle() | ||
| 113 | 113 | ||
| 114 | // pithy print | 114 | // pithy print |
| 115 | encoder(); | 115 | encoder(); |
| 116 | - pithy_print->elapse(SRS_RTMP_ENCODER_SLEEP_US / 1000); | 116 | + pithy_print->elapse(); |
| 117 | 117 | ||
| 118 | return ret; | 118 | return ret; |
| 119 | } | 119 | } |
| @@ -326,7 +326,7 @@ void SrsEncoder::encoder() | @@ -326,7 +326,7 @@ void SrsEncoder::encoder() | ||
| 326 | if (pithy_print->can_print()) { | 326 | if (pithy_print->can_print()) { |
| 327 | // TODO: FIXME: show more info. | 327 | // TODO: FIXME: show more info. |
| 328 | srs_trace("-> time=%"PRId64", encoders=%d, input=%s", | 328 | srs_trace("-> time=%"PRId64", encoders=%d, input=%s", |
| 329 | - pithy_print->get_age(), (int)ffmpegs.size(), input_stream_name.c_str()); | 329 | + pithy_print->age(), (int)ffmpegs.size(), input_stream_name.c_str()); |
| 330 | } | 330 | } |
| 331 | } | 331 | } |
| 332 | 332 |
| @@ -83,6 +83,7 @@ int SrsForwarder::on_publish(SrsRequest* req, std::string forward_server) | @@ -83,6 +83,7 @@ int SrsForwarder::on_publish(SrsRequest* req, std::string forward_server) | ||
| 83 | std::string s_port = RTMP_DEFAULT_PORT; | 83 | std::string s_port = RTMP_DEFAULT_PORT; |
| 84 | port = ::atoi(RTMP_DEFAULT_PORT); | 84 | port = ::atoi(RTMP_DEFAULT_PORT); |
| 85 | 85 | ||
| 86 | + // TODO: FIXME: parse complex params | ||
| 86 | size_t pos = forward_server.find(":"); | 87 | size_t pos = forward_server.find(":"); |
| 87 | if (pos != std::string::npos) { | 88 | if (pos != std::string::npos) { |
| 88 | s_port = forward_server.substr(pos + 1); | 89 | s_port = forward_server.substr(pos + 1); |
| @@ -310,6 +311,8 @@ int SrsForwarder::forward() | @@ -310,6 +311,8 @@ int SrsForwarder::forward() | ||
| 310 | // switch to other st-threads. | 311 | // switch to other st-threads. |
| 311 | st_usleep(0); | 312 | st_usleep(0); |
| 312 | 313 | ||
| 314 | + pithy_print.elapse(); | ||
| 315 | + | ||
| 313 | // read from client. | 316 | // read from client. |
| 314 | if (true) { | 317 | if (true) { |
| 315 | SrsCommonMessage* msg = NULL; | 318 | SrsCommonMessage* msg = NULL; |
| @@ -330,19 +333,18 @@ int SrsForwarder::forward() | @@ -330,19 +333,18 @@ int SrsForwarder::forward() | ||
| 330 | return ret; | 333 | return ret; |
| 331 | } | 334 | } |
| 332 | 335 | ||
| 336 | + // pithy print | ||
| 337 | + if (pithy_print.can_print()) { | ||
| 338 | + srs_trace("-> time=%"PRId64", msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", | ||
| 339 | + pithy_print.age(), count, client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps()); | ||
| 340 | + } | ||
| 341 | + | ||
| 333 | // ignore when no messages. | 342 | // ignore when no messages. |
| 334 | if (count <= 0) { | 343 | if (count <= 0) { |
| 335 | srs_verbose("no packets to forward."); | 344 | srs_verbose("no packets to forward."); |
| 336 | continue; | 345 | continue; |
| 337 | } | 346 | } |
| 338 | SrsAutoFree(SrsSharedPtrMessage*, msgs, true); | 347 | SrsAutoFree(SrsSharedPtrMessage*, msgs, true); |
| 339 | - | ||
| 340 | - // pithy print | ||
| 341 | - pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000); | ||
| 342 | - if (pithy_print.can_print()) { | ||
| 343 | - srs_trace("-> time=%"PRId64", msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", | ||
| 344 | - pithy_print.get_age(), count, client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps()); | ||
| 345 | - } | ||
| 346 | 348 | ||
| 347 | // all msgs to forward. | 349 | // all msgs to forward. |
| 348 | for (int i = 0; i < count; i++) { | 350 | for (int i = 0; i < count; i++) { |
| @@ -1470,10 +1470,10 @@ void SrsHls::hls_mux() | @@ -1470,10 +1470,10 @@ void SrsHls::hls_mux() | ||
| 1470 | { | 1470 | { |
| 1471 | // reportable | 1471 | // reportable |
| 1472 | if (pithy_print->can_print()) { | 1472 | if (pithy_print->can_print()) { |
| 1473 | - srs_trace("-> time=%"PRId64"", pithy_print->get_age()); | 1473 | + srs_trace("-> time=%"PRId64"", pithy_print->age()); |
| 1474 | } | 1474 | } |
| 1475 | 1475 | ||
| 1476 | - pithy_print->elapse(sample->cts); | 1476 | + pithy_print->elapse(); |
| 1477 | } | 1477 | } |
| 1478 | 1478 | ||
| 1479 | #endif | 1479 | #endif |
| @@ -188,7 +188,7 @@ int SrsIngester::cycle() | @@ -188,7 +188,7 @@ int SrsIngester::cycle() | ||
| 188 | 188 | ||
| 189 | // pithy print | 189 | // pithy print |
| 190 | ingester(); | 190 | ingester(); |
| 191 | - pithy_print->elapse(SRS_AUTO_INGESTER_SLEEP_US / 1000); | 191 | + pithy_print->elapse(); |
| 192 | 192 | ||
| 193 | return ret; | 193 | return ret; |
| 194 | } | 194 | } |
| @@ -350,7 +350,7 @@ void SrsIngester::ingester() | @@ -350,7 +350,7 @@ void SrsIngester::ingester() | ||
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | // TODO: FIXME: show more info. | 352 | // TODO: FIXME: show more info. |
| 353 | - srs_trace("-> time=%"PRId64", ingesters=%d", pithy_print->get_age(), (int)ingesters.size()); | 353 | + srs_trace("-> time=%"PRId64", ingesters=%d", pithy_print->age(), (int)ingesters.size()); |
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | int SrsIngester::on_reload_vhost_added(string vhost) | 356 | int SrsIngester::on_reload_vhost_added(string vhost) |
| @@ -30,6 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -30,6 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 30 | #include <srs_app_config.hpp> | 30 | #include <srs_app_config.hpp> |
| 31 | #include <srs_app_reload.hpp> | 31 | #include <srs_app_reload.hpp> |
| 32 | #include <srs_kernel_error.hpp> | 32 | #include <srs_kernel_error.hpp> |
| 33 | +#include <srs_kernel_utility.hpp> | ||
| 33 | 34 | ||
| 34 | #define SRS_STAGE_DEFAULT_INTERVAL_MS 1200 | 35 | #define SRS_STAGE_DEFAULT_INTERVAL_MS 1200 |
| 35 | 36 | ||
| @@ -75,6 +76,10 @@ struct SrsStageInfo : public ISrsReloadHandler | @@ -75,6 +76,10 @@ struct SrsStageInfo : public ISrsReloadHandler | ||
| 75 | pithy_print_time_ms = _srs_config->get_pithy_print_ingester(); | 76 | pithy_print_time_ms = _srs_config->get_pithy_print_ingester(); |
| 76 | break; | 77 | break; |
| 77 | } | 78 | } |
| 79 | + case SRS_STAGE_EDGE: { | ||
| 80 | + pithy_print_time_ms = _srs_config->get_pithy_print_edge(); | ||
| 81 | + break; | ||
| 82 | + } | ||
| 78 | case SRS_STAGE_HLS: { | 83 | case SRS_STAGE_HLS: { |
| 79 | pithy_print_time_ms = _srs_config->get_pithy_print_hls(); | 84 | pithy_print_time_ms = _srs_config->get_pithy_print_hls(); |
| 80 | break; | 85 | break; |
| @@ -98,7 +103,8 @@ SrsPithyPrint::SrsPithyPrint(int _stage_id) | @@ -98,7 +103,8 @@ SrsPithyPrint::SrsPithyPrint(int _stage_id) | ||
| 98 | { | 103 | { |
| 99 | stage_id = _stage_id; | 104 | stage_id = _stage_id; |
| 100 | client_id = enter_stage(); | 105 | client_id = enter_stage(); |
| 101 | - printed_age = age = 0; | 106 | + previous_tick = srs_get_system_time_ms(); |
| 107 | + printed_age = _age = 0; | ||
| 102 | } | 108 | } |
| 103 | 109 | ||
| 104 | SrsPithyPrint::~SrsPithyPrint() | 110 | SrsPithyPrint::~SrsPithyPrint() |
| @@ -138,9 +144,12 @@ void SrsPithyPrint::leave_stage() | @@ -138,9 +144,12 @@ void SrsPithyPrint::leave_stage() | ||
| 138 | stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms); | 144 | stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms); |
| 139 | } | 145 | } |
| 140 | 146 | ||
| 141 | -void SrsPithyPrint::elapse(int64_t time_ms) | 147 | +void SrsPithyPrint::elapse() |
| 142 | { | 148 | { |
| 143 | - age += time_ms; | 149 | + int64_t diff = srs_get_system_time_ms() - previous_tick; |
| 150 | + | ||
| 151 | + _age += srs_max(0, diff); | ||
| 152 | + previous_tick = srs_get_system_time_ms(); | ||
| 144 | } | 153 | } |
| 145 | 154 | ||
| 146 | bool SrsPithyPrint::can_print() | 155 | bool SrsPithyPrint::can_print() |
| @@ -148,24 +157,19 @@ bool SrsPithyPrint::can_print() | @@ -148,24 +157,19 @@ bool SrsPithyPrint::can_print() | ||
| 148 | SrsStageInfo* stage = _srs_stages[stage_id]; | 157 | SrsStageInfo* stage = _srs_stages[stage_id]; |
| 149 | srs_assert(stage != NULL); | 158 | srs_assert(stage != NULL); |
| 150 | 159 | ||
| 151 | - int64_t alive_age = age - printed_age; | 160 | + int64_t alive_age = _age - printed_age; |
| 152 | int64_t can_print_age = stage->nb_clients * stage->pithy_print_time_ms; | 161 | int64_t can_print_age = stage->nb_clients * stage->pithy_print_time_ms; |
| 153 | 162 | ||
| 154 | bool can_print = alive_age >= can_print_age; | 163 | bool can_print = alive_age >= can_print_age; |
| 155 | if (can_print) { | 164 | if (can_print) { |
| 156 | - printed_age = age; | 165 | + printed_age = _age; |
| 157 | } | 166 | } |
| 158 | 167 | ||
| 159 | return can_print; | 168 | return can_print; |
| 160 | } | 169 | } |
| 161 | 170 | ||
| 162 | -int64_t SrsPithyPrint::get_age() | ||
| 163 | -{ | ||
| 164 | - return age; | ||
| 165 | -} | ||
| 166 | - | ||
| 167 | -void SrsPithyPrint::set_age(int64_t _age) | 171 | +int64_t SrsPithyPrint::age() |
| 168 | { | 172 | { |
| 169 | - age = _age; | 173 | + return _age; |
| 170 | } | 174 | } |
| 171 | 175 |
| @@ -42,6 +42,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -42,6 +42,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 42 | #define SRS_STAGE_HLS 5 | 42 | #define SRS_STAGE_HLS 5 |
| 43 | // the pithy stage for all ingesters. | 43 | // the pithy stage for all ingesters. |
| 44 | #define SRS_STAGE_INGESTER 6 | 44 | #define SRS_STAGE_INGESTER 6 |
| 45 | +// the pithy stage for all edge. | ||
| 46 | +#define SRS_STAGE_EDGE 7 | ||
| 45 | 47 | ||
| 46 | /** | 48 | /** |
| 47 | * the stage is used for a collection of object to do print, | 49 | * the stage is used for a collection of object to do print, |
| @@ -55,8 +57,9 @@ private: | @@ -55,8 +57,9 @@ private: | ||
| 55 | int client_id; | 57 | int client_id; |
| 56 | int stage_id; | 58 | int stage_id; |
| 57 | // in ms. | 59 | // in ms. |
| 58 | - int64_t age; | 60 | + int64_t _age; |
| 59 | int64_t printed_age; | 61 | int64_t printed_age; |
| 62 | + int64_t previous_tick; | ||
| 60 | public: | 63 | public: |
| 61 | /** | 64 | /** |
| 62 | * @param _stage_id defined in SRS_STAGE_xxx, eg. SRS_STAGE_PLAY_USER. | 65 | * @param _stage_id defined in SRS_STAGE_xxx, eg. SRS_STAGE_PLAY_USER. |
| @@ -74,9 +77,9 @@ private: | @@ -74,9 +77,9 @@ private: | ||
| 74 | virtual void leave_stage(); | 77 | virtual void leave_stage(); |
| 75 | public: | 78 | public: |
| 76 | /** | 79 | /** |
| 77 | - * specified client elapse some time. | 80 | + * auto calc the elapse time |
| 78 | */ | 81 | */ |
| 79 | - virtual void elapse(int64_t time_ms); | 82 | + virtual void elapse(); |
| 80 | /** | 83 | /** |
| 81 | * whether current client can print. | 84 | * whether current client can print. |
| 82 | */ | 85 | */ |
| @@ -84,8 +87,7 @@ public: | @@ -84,8 +87,7 @@ public: | ||
| 84 | /** | 87 | /** |
| 85 | * get the elapsed time in ms. | 88 | * get the elapsed time in ms. |
| 86 | */ | 89 | */ |
| 87 | - virtual int64_t get_age(); | ||
| 88 | - virtual void set_age(int64_t _age); | 90 | + virtual int64_t age(); |
| 89 | }; | 91 | }; |
| 90 | 92 | ||
| 91 | #endif | 93 | #endif |
| @@ -297,8 +297,8 @@ int SrsRtmpConn::stream_service_cycle() | @@ -297,8 +297,8 @@ int SrsRtmpConn::stream_service_cycle() | ||
| 297 | srs_verbose("start to play stream %s.", req->stream.c_str()); | 297 | srs_verbose("start to play stream %s.", req->stream.c_str()); |
| 298 | 298 | ||
| 299 | if (vhost_is_edge) { | 299 | if (vhost_is_edge) { |
| 300 | - if ((ret = source->on_edge_play_stream()) != ERROR_SUCCESS) { | ||
| 301 | - srs_error("notice edge play stream failed. ret=%d", ret); | 300 | + if ((ret = source->on_edge_start_play()) != ERROR_SUCCESS) { |
| 301 | + srs_error("notice edge start play stream failed. ret=%d", ret); | ||
| 302 | return ret; | 302 | return ret; |
| 303 | } | 303 | } |
| 304 | } | 304 | } |
| @@ -311,9 +311,11 @@ int SrsRtmpConn::stream_service_cycle() | @@ -311,9 +311,11 @@ int SrsRtmpConn::stream_service_cycle() | ||
| 311 | srs_error("http hook on_play failed. ret=%d", ret); | 311 | srs_error("http hook on_play failed. ret=%d", ret); |
| 312 | return ret; | 312 | return ret; |
| 313 | } | 313 | } |
| 314 | + | ||
| 314 | srs_info("start to play stream %s success", req->stream.c_str()); | 315 | srs_info("start to play stream %s success", req->stream.c_str()); |
| 315 | ret = playing(source); | 316 | ret = playing(source); |
| 316 | on_stop(); | 317 | on_stop(); |
| 318 | + | ||
| 317 | return ret; | 319 | return ret; |
| 318 | } | 320 | } |
| 319 | case SrsRtmpConnFMLEPublish: { | 321 | case SrsRtmpConnFMLEPublish: { |
| @@ -423,10 +425,10 @@ int SrsRtmpConn::playing(SrsSource* source) | @@ -423,10 +425,10 @@ int SrsRtmpConn::playing(SrsSource* source) | ||
| 423 | 425 | ||
| 424 | int64_t starttime = -1; | 426 | int64_t starttime = -1; |
| 425 | while (true) { | 427 | while (true) { |
| 426 | - pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000); | ||
| 427 | - | ||
| 428 | // switch to other st-threads. | 428 | // switch to other st-threads. |
| 429 | st_usleep(0); | 429 | st_usleep(0); |
| 430 | + | ||
| 431 | + pithy_print.elapse(); | ||
| 430 | 432 | ||
| 431 | // read from client. | 433 | // read from client. |
| 432 | int ctl_msg_ret = ERROR_SUCCESS; | 434 | int ctl_msg_ret = ERROR_SUCCESS; |
| @@ -460,7 +462,7 @@ int SrsRtmpConn::playing(SrsSource* source) | @@ -460,7 +462,7 @@ int SrsRtmpConn::playing(SrsSource* source) | ||
| 460 | // reportable | 462 | // reportable |
| 461 | if (pithy_print.can_print()) { | 463 | if (pithy_print.can_print()) { |
| 462 | srs_trace("-> time=%"PRId64", duration=%"PRId64", cmr=%d, msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", | 464 | srs_trace("-> time=%"PRId64", duration=%"PRId64", cmr=%d, msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", |
| 463 | - pithy_print.get_age(), duration, ctl_msg_ret, count, rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps()); | 465 | + pithy_print.age(), duration, ctl_msg_ret, count, rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps()); |
| 464 | } | 466 | } |
| 465 | 467 | ||
| 466 | if (count <= 0) { | 468 | if (count <= 0) { |
| @@ -531,14 +533,15 @@ int SrsRtmpConn::fmle_publish(SrsSource* source) | @@ -531,14 +533,15 @@ int SrsRtmpConn::fmle_publish(SrsSource* source) | ||
| 531 | return ret; | 533 | return ret; |
| 532 | } | 534 | } |
| 533 | 535 | ||
| 536 | + srs_assert(msg); | ||
| 534 | SrsAutoFree(SrsCommonMessage, msg, false); | 537 | SrsAutoFree(SrsCommonMessage, msg, false); |
| 535 | 538 | ||
| 536 | - pithy_print.set_age(msg->header.timestamp); | 539 | + pithy_print.elapse(); |
| 537 | 540 | ||
| 538 | // reportable | 541 | // reportable |
| 539 | if (pithy_print.can_print()) { | 542 | if (pithy_print.can_print()) { |
| 540 | srs_trace("<- time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", | 543 | srs_trace("<- time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", |
| 541 | - pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps()); | 544 | + pithy_print.age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps()); |
| 542 | } | 545 | } |
| 543 | 546 | ||
| 544 | // process UnPublish event. | 547 | // process UnPublish event. |
| @@ -604,12 +607,12 @@ int SrsRtmpConn::flash_publish(SrsSource* source) | @@ -604,12 +607,12 @@ int SrsRtmpConn::flash_publish(SrsSource* source) | ||
| 604 | 607 | ||
| 605 | SrsAutoFree(SrsCommonMessage, msg, false); | 608 | SrsAutoFree(SrsCommonMessage, msg, false); |
| 606 | 609 | ||
| 607 | - pithy_print.set_age(msg->header.timestamp); | 610 | + pithy_print.elapse(); |
| 608 | 611 | ||
| 609 | // reportable | 612 | // reportable |
| 610 | if (pithy_print.can_print()) { | 613 | if (pithy_print.can_print()) { |
| 611 | srs_trace("<- time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", | 614 | srs_trace("<- time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", |
| 612 | - pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps()); | 615 | + pithy_print.age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps()); |
| 613 | } | 616 | } |
| 614 | 617 | ||
| 615 | // process UnPublish event. | 618 | // process UnPublish event. |
| @@ -515,7 +515,7 @@ int SrsSource::initialize() | @@ -515,7 +515,7 @@ int SrsSource::initialize() | ||
| 515 | } | 515 | } |
| 516 | #endif | 516 | #endif |
| 517 | 517 | ||
| 518 | - if ((ret = edge->initialize(_req)) != ERROR_SUCCESS) { | 518 | + if ((ret = edge->initialize(this, _req)) != ERROR_SUCCESS) { |
| 519 | return ret; | 519 | return ret; |
| 520 | } | 520 | } |
| 521 | 521 | ||
| @@ -1168,6 +1168,10 @@ void SrsSource::on_consumer_destroy(SrsConsumer* consumer) | @@ -1168,6 +1168,10 @@ void SrsSource::on_consumer_destroy(SrsConsumer* consumer) | ||
| 1168 | consumers.erase(it); | 1168 | consumers.erase(it); |
| 1169 | } | 1169 | } |
| 1170 | srs_info("handle consumer destroy success."); | 1170 | srs_info("handle consumer destroy success."); |
| 1171 | + | ||
| 1172 | + if (consumers.empty()) { | ||
| 1173 | + edge->on_all_client_stop(); | ||
| 1174 | + } | ||
| 1171 | } | 1175 | } |
| 1172 | 1176 | ||
| 1173 | void SrsSource::set_cache(bool enabled) | 1177 | void SrsSource::set_cache(bool enabled) |
| @@ -1180,7 +1184,7 @@ bool SrsSource::is_atc() | @@ -1180,7 +1184,7 @@ bool SrsSource::is_atc() | ||
| 1180 | return atc; | 1184 | return atc; |
| 1181 | } | 1185 | } |
| 1182 | 1186 | ||
| 1183 | -int SrsSource::on_edge_play_stream() | 1187 | +int SrsSource::on_edge_start_play() |
| 1184 | { | 1188 | { |
| 1185 | return edge->on_client_play(); | 1189 | return edge->on_client_play(); |
| 1186 | } | 1190 | } |
| @@ -313,7 +313,7 @@ public: | @@ -313,7 +313,7 @@ public: | ||
| 313 | // for consumer, atc feature. | 313 | // for consumer, atc feature. |
| 314 | virtual bool is_atc(); | 314 | virtual bool is_atc(); |
| 315 | // for edge, when play edge stream, check the state | 315 | // for edge, when play edge stream, check the state |
| 316 | - virtual int on_edge_play_stream(); | 316 | + virtual int on_edge_start_play(); |
| 317 | private: | 317 | private: |
| 318 | virtual int create_forwarders(); | 318 | virtual int create_forwarders(); |
| 319 | virtual void destroy_forwarders(); | 319 | virtual void destroy_forwarders(); |
| @@ -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 "76" | 34 | +#define VERSION_REVISION "77" |
| 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" |
| @@ -337,6 +337,11 @@ SrsRtmpClient::~SrsRtmpClient() | @@ -337,6 +337,11 @@ SrsRtmpClient::~SrsRtmpClient() | ||
| 337 | srs_freep(hs_bytes); | 337 | srs_freep(hs_bytes); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | +SrsProtocol* SrsRtmpClient::get_protocol() | ||
| 341 | +{ | ||
| 342 | + return protocol; | ||
| 343 | +} | ||
| 344 | + | ||
| 340 | void SrsRtmpClient::set_recv_timeout(int64_t timeout_us) | 345 | void SrsRtmpClient::set_recv_timeout(int64_t timeout_us) |
| 341 | { | 346 | { |
| 342 | protocol->set_recv_timeout(timeout_us); | 347 | protocol->set_recv_timeout(timeout_us); |
| @@ -155,6 +155,7 @@ public: | @@ -155,6 +155,7 @@ public: | ||
| 155 | SrsRtmpClient(ISrsProtocolReaderWriter* skt); | 155 | SrsRtmpClient(ISrsProtocolReaderWriter* skt); |
| 156 | virtual ~SrsRtmpClient(); | 156 | virtual ~SrsRtmpClient(); |
| 157 | public: | 157 | public: |
| 158 | + virtual SrsProtocol* get_protocol(); | ||
| 158 | virtual void set_recv_timeout(int64_t timeout_us); | 159 | virtual void set_recv_timeout(int64_t timeout_us); |
| 159 | virtual void set_send_timeout(int64_t timeout_us); | 160 | virtual void set_send_timeout(int64_t timeout_us); |
| 160 | virtual int64_t get_recv_bytes(); | 161 | virtual int64_t get_recv_bytes(); |
-
请 注册 或 登录 后发表评论