winlin

performance refine, support 3k+ connections(270kbps). 0.9.130

@@ -241,6 +241,7 @@ Supported operating systems and hardware: @@ -241,6 +241,7 @@ Supported operating systems and hardware:
241 * 2013-10-17, Created.<br/> 241 * 2013-10-17, Created.<br/>
242 242
243 ## History 243 ## History
  244 +* v1.0, 2014-06-22, performance refine, support 3k+ connections(270kbps). 0.9.130
244 * v1.0, 2014-06-21, support edge [token traverse](https://github.com/winlinvip/simple-rtmp-server/wiki/DRM#tokentraverse), fix [#104](https://github.com/winlinvip/simple-rtmp-server/issues/104). 0.9.129 245 * v1.0, 2014-06-21, support edge [token traverse](https://github.com/winlinvip/simple-rtmp-server/wiki/DRM#tokentraverse), fix [#104](https://github.com/winlinvip/simple-rtmp-server/issues/104). 0.9.129
245 * v1.0, 2014-06-19, add connections count to api summaries. 0.9.127 246 * v1.0, 2014-06-19, add connections count to api summaries. 0.9.127
246 * v1.0, 2014-06-19, add srs bytes and kbps to api summaries. 0.9.126 247 * v1.0, 2014-06-19, add srs bytes and kbps to api summaries. 0.9.126
@@ -36,7 +36,7 @@ srs_log_level trace; @@ -36,7 +36,7 @@ srs_log_level trace;
36 srs_log_file ./objs/srs.log; 36 srs_log_file ./objs/srs.log;
37 # the max connections. 37 # the max connections.
38 # if exceed the max connections, server will drop the new connection. 38 # if exceed the max connections, server will drop the new connection.
39 -# default: 2000 39 +# default: 12345
40 max_connections 1000; 40 max_connections 1000;
41 # whether start as deamon 41 # whether start as deamon
42 # @remark: donot support reload. 42 # @remark: donot support reload.
@@ -456,7 +456,7 @@ MODULE_ID="RTMP" @@ -456,7 +456,7 @@ MODULE_ID="RTMP"
456 MODULE_DEPENDS=("CORE" "KERNEL") 456 MODULE_DEPENDS=("CORE" "KERNEL")
457 ModuleLibIncs=(${SRS_OBJS} ${LibSSLRoot}) 457 ModuleLibIncs=(${SRS_OBJS} ${LibSSLRoot})
458 MODULE_FILES=("srs_protocol_amf0" "srs_protocol_io" "srs_protocol_rtmp_stack" "srs_protocol_rtmp" 458 MODULE_FILES=("srs_protocol_amf0" "srs_protocol_io" "srs_protocol_rtmp_stack" "srs_protocol_rtmp"
459 - "srs_protocol_handshake" "srs_protocol_utility") 459 + "srs_protocol_handshake" "srs_protocol_utility" "srs_protocol_msg_array")
460 RTMP_INCS="src/rtmp"; MODULE_DIR=${RTMP_INCS} . auto/modules.sh 460 RTMP_INCS="src/rtmp"; MODULE_DIR=${RTMP_INCS} . auto/modules.sh
461 RTMP_OBJS="${MODULE_OBJS[@]}" 461 RTMP_OBJS="${MODULE_OBJS[@]}"
462 # 462 #
@@ -1403,7 +1403,7 @@ int SrsConfig::get_max_connections() @@ -1403,7 +1403,7 @@ int SrsConfig::get_max_connections()
1403 1403
1404 SrsConfDirective* conf = root->get("max_connections"); 1404 SrsConfDirective* conf = root->get("max_connections");
1405 if (!conf || conf->arg0().empty()) { 1405 if (!conf || conf->arg0().empty()) {
1406 - return 2000; 1406 + return SRS_CONF_DEFAULT_MAX_CONNECTIONS;
1407 } 1407 }
1408 1408
1409 return ::atoi(conf->arg0().c_str()); 1409 return ::atoi(conf->arg0().c_str());
@@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 #define SRS_CONF_DEFAULT_PID_FILE "./objs/srs.pid" 38 #define SRS_CONF_DEFAULT_PID_FILE "./objs/srs.pid"
39 #define SRS_DEFAULT_CONF "conf/srs.conf" 39 #define SRS_DEFAULT_CONF "conf/srs.conf"
40 40
  41 +#define SRS_CONF_DEFAULT_MAX_CONNECTIONS 12345
41 #define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html" 42 #define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html"
42 #define SRS_CONF_DEFAULT_HLS_FRAGMENT 10 43 #define SRS_CONF_DEFAULT_HLS_FRAGMENT 10
43 #define SRS_CONF_DEFAULT_HLS_WINDOW 60 44 #define SRS_CONF_DEFAULT_HLS_WINDOW 60
@@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44 #include <srs_app_socket.hpp> 44 #include <srs_app_socket.hpp>
45 #include <srs_app_kbps.hpp> 45 #include <srs_app_kbps.hpp>
46 #include <srs_kernel_utility.hpp> 46 #include <srs_kernel_utility.hpp>
  47 +#include <srs_protocol_msg_array.hpp>
47 48
48 // when error, edge ingester sleep for a while and retry. 49 // when error, edge ingester sleep for a while and retry.
49 #define SRS_EDGE_INGESTER_SLEEP_US (int64_t)(1*1000*1000LL) 50 #define SRS_EDGE_INGESTER_SLEEP_US (int64_t)(1*1000*1000LL)
@@ -431,6 +432,7 @@ void SrsEdgeForwarder::stop() @@ -431,6 +432,7 @@ void SrsEdgeForwarder::stop()
431 kbps->set_io(NULL, NULL); 432 kbps->set_io(NULL, NULL);
432 } 433 }
433 434
  435 +#define SYS_MAX_EDGE_SEND_MSGS 128
434 int SrsEdgeForwarder::cycle() 436 int SrsEdgeForwarder::cycle()
435 { 437 {
436 int ret = ERROR_SUCCESS; 438 int ret = ERROR_SUCCESS;
@@ -438,6 +440,8 @@ int SrsEdgeForwarder::cycle() @@ -438,6 +440,8 @@ int SrsEdgeForwarder::cycle()
438 client->set_recv_timeout(SRS_PULSE_TIMEOUT_US); 440 client->set_recv_timeout(SRS_PULSE_TIMEOUT_US);
439 441
440 SrsPithyPrint pithy_print(SRS_STAGE_EDGE); 442 SrsPithyPrint pithy_print(SRS_STAGE_EDGE);
  443 +
  444 + SrsSharedPtrMessageArray msgs(SYS_MAX_EDGE_SEND_MSGS);
441 445
442 while (pthread->can_loop()) { 446 while (pthread->can_loop()) {
443 // switch to other st-threads. 447 // switch to other st-threads.
@@ -465,8 +469,7 @@ int SrsEdgeForwarder::cycle() @@ -465,8 +469,7 @@ int SrsEdgeForwarder::cycle()
465 469
466 // forward all messages. 470 // forward all messages.
467 int count = 0; 471 int count = 0;
468 - SrsSharedPtrMessage** msgs = NULL;  
469 - if ((ret = queue->get_packets(0, msgs, count)) != ERROR_SUCCESS) { 472 + if ((ret = queue->dump_packets(msgs.size, msgs.msgs, count)) != ERROR_SUCCESS) {
470 srs_error("get message to forward to origin failed. ret=%d", ret); 473 srs_error("get message to forward to origin failed. ret=%d", ret);
471 return ret; 474 return ret;
472 } 475 }
@@ -488,16 +491,15 @@ int SrsEdgeForwarder::cycle() @@ -488,16 +491,15 @@ int SrsEdgeForwarder::cycle()
488 srs_verbose("no packets to forward."); 491 srs_verbose("no packets to forward.");
489 continue; 492 continue;
490 } 493 }
491 - SrsAutoFreeArray(SrsSharedPtrMessage, msgs, count);  
492 494
493 // all msgs to forward to origin. 495 // all msgs to forward to origin.
494 // @remark, becareful, all msgs must be free explicitly, 496 // @remark, becareful, all msgs must be free explicitly,
495 // free by send_and_free_message or srs_freep. 497 // free by send_and_free_message or srs_freep.
496 for (int i = 0; i < count; i++) { 498 for (int i = 0; i < count; i++) {
497 - SrsSharedPtrMessage* msg = msgs[i]; 499 + SrsSharedPtrMessage* msg = msgs.msgs[i];
498 500
499 srs_assert(msg); 501 srs_assert(msg);
500 - msgs[i] = NULL; 502 + msgs.msgs[i] = NULL;
501 503
502 if ((ret = client->send_and_free_message(msg, stream_id)) != ERROR_SUCCESS) { 504 if ((ret = client->send_and_free_message(msg, stream_id)) != ERROR_SUCCESS) {
503 srs_error("edge publish forwarder send message to server failed. ret=%d", ret); 505 srs_error("edge publish forwarder send message to server failed. ret=%d", ret);
@@ -41,6 +41,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -41,6 +41,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 #include <srs_protocol_rtmp.hpp> 41 #include <srs_protocol_rtmp.hpp>
42 #include <srs_app_kbps.hpp> 42 #include <srs_app_kbps.hpp>
43 #include <srs_kernel_utility.hpp> 43 #include <srs_kernel_utility.hpp>
  44 +#include <srs_protocol_msg_array.hpp>
44 45
45 // when error, forwarder sleep for a while and retry. 46 // when error, forwarder sleep for a while and retry.
46 #define SRS_FORWARDER_SLEEP_US (int64_t)(3*1000*1000LL) 47 #define SRS_FORWARDER_SLEEP_US (int64_t)(3*1000*1000LL)
@@ -309,6 +310,7 @@ int SrsForwarder::connect_server() @@ -309,6 +310,7 @@ int SrsForwarder::connect_server()
309 return ret; 310 return ret;
310 } 311 }
311 312
  313 +#define SYS_MAX_FORWARD_SEND_MSGS 128
312 int SrsForwarder::forward() 314 int SrsForwarder::forward()
313 { 315 {
314 int ret = ERROR_SUCCESS; 316 int ret = ERROR_SUCCESS;
@@ -317,6 +319,8 @@ int SrsForwarder::forward() @@ -317,6 +319,8 @@ int SrsForwarder::forward()
317 319
318 SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER); 320 SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER);
319 321
  322 + SrsSharedPtrMessageArray msgs(SYS_MAX_FORWARD_SEND_MSGS);
  323 +
320 while (pthread->can_loop()) { 324 while (pthread->can_loop()) {
321 // switch to other st-threads. 325 // switch to other st-threads.
322 st_usleep(0); 326 st_usleep(0);
@@ -339,8 +343,7 @@ int SrsForwarder::forward() @@ -339,8 +343,7 @@ int SrsForwarder::forward()
339 343
340 // forward all messages. 344 // forward all messages.
341 int count = 0; 345 int count = 0;
342 - SrsSharedPtrMessage** msgs = NULL;  
343 - if ((ret = queue->get_packets(0, msgs, count)) != ERROR_SUCCESS) { 346 + if ((ret = queue->dump_packets(msgs.size, msgs.msgs, count)) != ERROR_SUCCESS) {
344 srs_error("get message to forward failed. ret=%d", ret); 347 srs_error("get message to forward failed. ret=%d", ret);
345 return ret; 348 return ret;
346 } 349 }
@@ -360,16 +363,15 @@ int SrsForwarder::forward() @@ -360,16 +363,15 @@ int SrsForwarder::forward()
360 srs_verbose("no packets to forward."); 363 srs_verbose("no packets to forward.");
361 continue; 364 continue;
362 } 365 }
363 - SrsAutoFreeArray(SrsSharedPtrMessage, msgs, count);  
364 366
365 // all msgs to forward. 367 // all msgs to forward.
366 // @remark, becareful, all msgs must be free explicitly, 368 // @remark, becareful, all msgs must be free explicitly,
367 // free by send_and_free_message or srs_freep. 369 // free by send_and_free_message or srs_freep.
368 for (int i = 0; i < count; i++) { 370 for (int i = 0; i < count; i++) {
369 - SrsSharedPtrMessage* msg = msgs[i]; 371 + SrsSharedPtrMessage* msg = msgs.msgs[i];
370 372
371 srs_assert(msg); 373 srs_assert(msg);
372 - msgs[i] = NULL; 374 + msgs.msgs[i] = NULL;
373 375
374 if ((ret = client->send_and_free_message(msg, stream_id)) != ERROR_SUCCESS) { 376 if ((ret = client->send_and_free_message(msg, stream_id)) != ERROR_SUCCESS) {
375 srs_error("forwarder send message to server failed. ret=%d", ret); 377 srs_error("forwarder send message to server failed. ret=%d", ret);
@@ -50,6 +50,7 @@ using namespace std; @@ -50,6 +50,7 @@ using namespace std;
50 #include <srs_app_utility.hpp> 50 #include <srs_app_utility.hpp>
51 #include <srs_protocol_utility.hpp> 51 #include <srs_protocol_utility.hpp>
52 #include <srs_kernel_utility.hpp> 52 #include <srs_kernel_utility.hpp>
  53 +#include <srs_protocol_msg_array.hpp>
53 54
54 // when stream is busy, for example, streaming is already 55 // when stream is busy, for example, streaming is already
55 // publishing, when a new client to request to publish, 56 // publishing, when a new client to request to publish,
@@ -382,7 +383,7 @@ int SrsRtmpConn::stream_service_cycle() @@ -382,7 +383,7 @@ int SrsRtmpConn::stream_service_cycle()
382 } 383 }
383 384
384 srs_info("start to publish stream %s success", req->stream.c_str()); 385 srs_info("start to publish stream %s success", req->stream.c_str());
385 - ret = fmle_publish(source); 386 + ret = fmle_publishing(source);
386 387
387 // when edge, notice edge to change state. 388 // when edge, notice edge to change state.
388 // when origin, notice all service to unpublish. 389 // when origin, notice all service to unpublish.
@@ -416,7 +417,7 @@ int SrsRtmpConn::stream_service_cycle() @@ -416,7 +417,7 @@ int SrsRtmpConn::stream_service_cycle()
416 } 417 }
417 418
418 srs_info("flash start to publish stream %s success", req->stream.c_str()); 419 srs_info("flash start to publish stream %s success", req->stream.c_str());
419 - ret = flash_publish(source); 420 + ret = flash_publishing(source);
420 421
421 // when edge, notice edge to change state. 422 // when edge, notice edge to change state.
422 // when origin, notice all service to unpublish. 423 // when origin, notice all service to unpublish.
@@ -476,6 +477,8 @@ int SrsRtmpConn::check_vhost() @@ -476,6 +477,8 @@ int SrsRtmpConn::check_vhost()
476 return ret; 477 return ret;
477 } 478 }
478 479
  480 +#define SYS_MAX_PLAY_SEND_MSGS 128
  481 +
479 int SrsRtmpConn::playing(SrsSource* source) 482 int SrsRtmpConn::playing(SrsSource* source)
480 { 483 {
481 int ret = ERROR_SUCCESS; 484 int ret = ERROR_SUCCESS;
@@ -499,38 +502,43 @@ int SrsRtmpConn::playing(SrsSource* source) @@ -499,38 +502,43 @@ int SrsRtmpConn::playing(SrsSource* source)
499 rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_US); 502 rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_US);
500 503
501 SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER); 504 SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER);
  505 +
  506 + SrsSharedPtrMessageArray msgs(SYS_MAX_PLAY_SEND_MSGS);
502 507
  508 + bool user_specified_duration_to_stop = (req->duration > 0);
503 int64_t starttime = -1; 509 int64_t starttime = -1;
  510 +
504 while (true) { 511 while (true) {
505 - // switch to other st-threads.  
506 - st_usleep(0);  
507 - 512 + // collect elapse for pithy print.
508 pithy_print.elapse(); 513 pithy_print.elapse();
509 514
510 // read from client. 515 // read from client.
511 if (true) { 516 if (true) {
512 SrsMessage* msg = NULL; 517 SrsMessage* msg = NULL;
513 ret = rtmp->recv_message(&msg); 518 ret = rtmp->recv_message(&msg);
514 -  
515 srs_verbose("play loop recv message. ret=%d", ret); 519 srs_verbose("play loop recv message. ret=%d", ret);
516 - if (ret != ERROR_SUCCESS && ret != ERROR_SOCKET_TIMEOUT) {  
517 - if (ret != ERROR_SOCKET_TIMEOUT && !srs_is_client_gracefully_close(ret)) { 520 +
  521 + if (ret == ERROR_SOCKET_TIMEOUT) {
  522 + // it's ok, do nothing.
  523 + ret = ERROR_SUCCESS;
  524 + } else if (ret != ERROR_SUCCESS) {
  525 + if (!srs_is_client_gracefully_close(ret)) {
518 srs_error("recv client control message failed. ret=%d", ret); 526 srs_error("recv client control message failed. ret=%d", ret);
519 } 527 }
520 return ret; 528 return ret;
521 - }  
522 - if ((ret = process_play_control_msg(consumer, msg)) != ERROR_SUCCESS) {  
523 - if (!srs_is_system_control_error(ret)) {  
524 - srs_error("process play control message failed. ret=%d", ret); 529 + } else {
  530 + if ((ret = process_play_control_msg(consumer, msg)) != ERROR_SUCCESS) {
  531 + if (!srs_is_system_control_error(ret)) {
  532 + srs_error("process play control message failed. ret=%d", ret);
  533 + }
  534 + return ret;
525 } 535 }
526 - return ret;  
527 } 536 }
528 } 537 }
529 538
530 // get messages from consumer. 539 // get messages from consumer.
531 - SrsSharedPtrMessage** msgs = NULL;  
532 int count = 0; 540 int count = 0;
533 - if ((ret = consumer->get_packets(0, msgs, count)) != ERROR_SUCCESS) { 541 + if ((ret = consumer->dump_packets(msgs.size, msgs.msgs, count)) != ERROR_SUCCESS) {
534 srs_error("get messages from consumer failed. ret=%d", ret); 542 srs_error("get messages from consumer failed. ret=%d", ret);
535 return ret; 543 return ret;
536 } 544 }
@@ -545,32 +553,29 @@ int SrsRtmpConn::playing(SrsSource* source) @@ -545,32 +553,29 @@ int SrsRtmpConn::playing(SrsSource* source)
545 kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m()); 553 kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m());
546 } 554 }
547 555
548 - if (count <= 0) {  
549 - srs_verbose("no packets in queue.");  
550 - continue;  
551 - }  
552 - SrsAutoFreeArray(SrsSharedPtrMessage, msgs, count);  
553 -  
554 // sendout messages 556 // sendout messages
555 // @remark, becareful, all msgs must be free explicitly, 557 // @remark, becareful, all msgs must be free explicitly,
556 // free by send_and_free_message or srs_freep. 558 // free by send_and_free_message or srs_freep.
557 for (int i = 0; i < count; i++) { 559 for (int i = 0; i < count; i++) {
558 - SrsSharedPtrMessage* msg = msgs[i]; 560 + SrsSharedPtrMessage* msg = msgs.msgs[i];
559 561
560 // the send_message will free the msg, 562 // the send_message will free the msg,
561 // so set the msgs[i] to NULL. 563 // so set the msgs[i] to NULL.
562 - msgs[i] = NULL;  
563 -  
564 - srs_assert(msg); 564 + msgs.msgs[i] = NULL;
565 565
566 - // foreach msg, collect the duration.  
567 - // @remark: never use msg when sent it, for the protocol sdk will free it.  
568 - if (starttime < 0 || starttime > msg->header.timestamp) { 566 + // only when user specifies the duration,
  567 + // we start to collect the durations for each message.
  568 + if (user_specified_duration_to_stop) {
  569 + // foreach msg, collect the duration.
  570 + // @remark: never use msg when sent it, for the protocol sdk will free it.
  571 + if (starttime < 0 || starttime > msg->header.timestamp) {
  572 + starttime = msg->header.timestamp;
  573 + }
  574 + duration += msg->header.timestamp - starttime;
569 starttime = msg->header.timestamp; 575 starttime = msg->header.timestamp;
570 } 576 }
571 - duration += msg->header.timestamp - starttime;  
572 - starttime = msg->header.timestamp;  
573 577
  578 + // no need to assert msg, for the rtmp will assert it.
574 if ((ret = rtmp->send_and_free_message(msg, res->stream_id)) != ERROR_SUCCESS) { 579 if ((ret = rtmp->send_and_free_message(msg, res->stream_id)) != ERROR_SUCCESS) {
575 srs_error("send message to client failed. ret=%d", ret); 580 srs_error("send message to client failed. ret=%d", ret);
576 return ret; 581 return ret;
@@ -579,17 +584,22 @@ int SrsRtmpConn::playing(SrsSource* source) @@ -579,17 +584,22 @@ int SrsRtmpConn::playing(SrsSource* source)
579 584
580 // if duration specified, and exceed it, stop play live. 585 // if duration specified, and exceed it, stop play live.
581 // @see: https://github.com/winlinvip/simple-rtmp-server/issues/45 586 // @see: https://github.com/winlinvip/simple-rtmp-server/issues/45
582 - if (req->duration > 0 && duration >= (int64_t)req->duration) {  
583 - ret = ERROR_RTMP_DURATION_EXCEED;  
584 - srs_trace("stop live for duration exceed. ret=%d", ret);  
585 - return ret; 587 + if (user_specified_duration_to_stop) {
  588 + if (duration >= (int64_t)req->duration) {
  589 + ret = ERROR_RTMP_DURATION_EXCEED;
  590 + srs_trace("stop live for duration exceed. ret=%d", ret);
  591 + return ret;
  592 + }
586 } 593 }
  594 +
  595 + // switch to other threads, to anti dead loop.
  596 + st_usleep(0);
587 } 597 }
588 598
589 return ret; 599 return ret;
590 } 600 }
591 601
592 -int SrsRtmpConn::fmle_publish(SrsSource* source) 602 +int SrsRtmpConn::fmle_publishing(SrsSource* source)
593 { 603 {
594 int ret = ERROR_SUCCESS; 604 int ret = ERROR_SUCCESS;
595 605
@@ -668,7 +678,7 @@ int SrsRtmpConn::fmle_publish(SrsSource* source) @@ -668,7 +678,7 @@ int SrsRtmpConn::fmle_publish(SrsSource* source)
668 return ret; 678 return ret;
669 } 679 }
670 680
671 -int SrsRtmpConn::flash_publish(SrsSource* source) 681 +int SrsRtmpConn::flash_publishing(SrsSource* source)
672 { 682 {
673 int ret = ERROR_SUCCESS; 683 int ret = ERROR_SUCCESS;
674 684
@@ -48,6 +48,7 @@ class SrsHttpHooks; @@ -48,6 +48,7 @@ class SrsHttpHooks;
48 class SrsBandwidth; 48 class SrsBandwidth;
49 class SrsKbps; 49 class SrsKbps;
50 class SrsRtmpClient; 50 class SrsRtmpClient;
  51 +class SrsSharedPtrMessage;
51 52
52 /** 53 /**
53 * the client provides the main logic control for RTMP clients. 54 * the client provides the main logic control for RTMP clients.
@@ -87,8 +88,8 @@ private: @@ -87,8 +88,8 @@ private:
87 virtual int stream_service_cycle(); 88 virtual int stream_service_cycle();
88 virtual int check_vhost(); 89 virtual int check_vhost();
89 virtual int playing(SrsSource* source); 90 virtual int playing(SrsSource* source);
90 - virtual int fmle_publish(SrsSource* source);  
91 - virtual int flash_publish(SrsSource* source); 91 + virtual int fmle_publishing(SrsSource* source);
  92 + virtual int flash_publishing(SrsSource* source);
92 virtual int process_publish_message(SrsSource* source, SrsMessage* msg, bool vhost_is_edge); 93 virtual int process_publish_message(SrsSource* source, SrsMessage* msg, bool vhost_is_edge);
93 virtual int process_play_control_msg(SrsConsumer* consumer, SrsMessage* msg); 94 virtual int process_play_control_msg(SrsConsumer* consumer, SrsMessage* msg);
94 private: 95 private:
@@ -136,7 +136,7 @@ int SrsMessageQueue::enqueue(SrsSharedPtrMessage* msg) @@ -136,7 +136,7 @@ int SrsMessageQueue::enqueue(SrsSharedPtrMessage* msg)
136 { 136 {
137 int ret = ERROR_SUCCESS; 137 int ret = ERROR_SUCCESS;
138 138
139 - if (msg->header.is_video() || msg->header.is_audio()) { 139 + if (msg->header.is_audio() || msg->header.is_video()) {
140 if (av_start_time == -1) { 140 if (av_start_time == -1) {
141 av_start_time = msg->header.timestamp; 141 av_start_time = msg->header.timestamp;
142 } 142 }
@@ -153,7 +153,7 @@ int SrsMessageQueue::enqueue(SrsSharedPtrMessage* msg) @@ -153,7 +153,7 @@ int SrsMessageQueue::enqueue(SrsSharedPtrMessage* msg)
153 return ret; 153 return ret;
154 } 154 }
155 155
156 -int SrsMessageQueue::get_packets(int max_count, SrsSharedPtrMessage**& pmsgs, int& count) 156 +int SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count)
157 { 157 {
158 int ret = ERROR_SUCCESS; 158 int ret = ERROR_SUCCESS;
159 159
@@ -161,17 +161,8 @@ int SrsMessageQueue::get_packets(int max_count, SrsSharedPtrMessage**& pmsgs, in @@ -161,17 +161,8 @@ int SrsMessageQueue::get_packets(int max_count, SrsSharedPtrMessage**& pmsgs, in
161 return ret; 161 return ret;
162 } 162 }
163 163
164 - if (max_count == 0) {  
165 - count = (int)msgs.size();  
166 - } else {  
167 - count = srs_min(max_count, (int)msgs.size());  
168 - }  
169 -  
170 - if (count <= 0) {  
171 - return ret;  
172 - }  
173 -  
174 - pmsgs = new SrsSharedPtrMessage*[count]; 164 + srs_assert(max_count > 0);
  165 + count = srs_min(max_count, (int)msgs.size());
175 166
176 for (int i = 0; i < count; i++) { 167 for (int i = 0; i < count; i++) {
177 pmsgs[i] = msgs[i]; 168 pmsgs[i] = msgs[i];
@@ -275,11 +266,11 @@ int SrsConsumer::get_time() @@ -275,11 +266,11 @@ int SrsConsumer::get_time()
275 return jitter->get_time(); 266 return jitter->get_time();
276 } 267 }
277 268
278 -int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, int tba, int tbv) 269 +int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv)
279 { 270 {
280 int ret = ERROR_SUCCESS; 271 int ret = ERROR_SUCCESS;
281 272
282 - if (!source->is_atc()) { 273 + if (!atc) {
283 if ((ret = jitter->correct(msg, tba, tbv)) != ERROR_SUCCESS) { 274 if ((ret = jitter->correct(msg, tba, tbv)) != ERROR_SUCCESS) {
284 srs_freep(msg); 275 srs_freep(msg);
285 return ret; 276 return ret;
@@ -293,8 +284,10 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, int tba, int tbv) @@ -293,8 +284,10 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, int tba, int tbv)
293 return ret; 284 return ret;
294 } 285 }
295 286
296 -int SrsConsumer::get_packets(int max_count, SrsSharedPtrMessage**& pmsgs, int& count) 287 +int SrsConsumer::dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count)
297 { 288 {
  289 + srs_assert(max_count > 0);
  290 +
298 if (should_update_source_id) { 291 if (should_update_source_id) {
299 srs_trace("update source_id=%d", source->source_id()); 292 srs_trace("update source_id=%d", source->source_id());
300 should_update_source_id = false; 293 should_update_source_id = false;
@@ -305,7 +298,7 @@ int SrsConsumer::get_packets(int max_count, SrsSharedPtrMessage**& pmsgs, int& c @@ -305,7 +298,7 @@ int SrsConsumer::get_packets(int max_count, SrsSharedPtrMessage**& pmsgs, int& c
305 return ERROR_SUCCESS; 298 return ERROR_SUCCESS;
306 } 299 }
307 300
308 - return queue->get_packets(max_count, pmsgs, count); 301 + return queue->dump_packets(max_count, pmsgs, count);
309 } 302 }
310 303
311 int SrsConsumer::on_play_client_pause(bool is_pause) 304 int SrsConsumer::on_play_client_pause(bool is_pause)
@@ -391,14 +384,15 @@ void SrsGopCache::clear() @@ -391,14 +384,15 @@ void SrsGopCache::clear()
391 cached_video_count = 0; 384 cached_video_count = 0;
392 } 385 }
393 386
394 -int SrsGopCache::dump(SrsConsumer* consumer, int tba, int tbv) 387 +int SrsGopCache::dump(SrsConsumer* consumer, bool atc, int tba, int tbv)
395 { 388 {
396 int ret = ERROR_SUCCESS; 389 int ret = ERROR_SUCCESS;
397 390
398 std::vector<SrsSharedPtrMessage*>::iterator it; 391 std::vector<SrsSharedPtrMessage*>::iterator it;
399 for (it = gop_cache.begin(); it != gop_cache.end(); ++it) { 392 for (it = gop_cache.begin(); it != gop_cache.end(); ++it) {
400 SrsSharedPtrMessage* msg = *it; 393 SrsSharedPtrMessage* msg = *it;
401 - if ((ret = consumer->enqueue(msg->copy(), tba, tbv)) != ERROR_SUCCESS) { 394 + SrsSharedPtrMessage* copy = msg->copy();
  395 + if ((ret = consumer->enqueue(copy, atc, tba, tbv)) != ERROR_SUCCESS) {
402 srs_error("dispatch cached gop failed. ret=%d", ret); 396 srs_error("dispatch cached gop failed. ret=%d", ret);
403 return ret; 397 return ret;
404 } 398 }
@@ -926,7 +920,8 @@ int SrsSource::on_meta_data(SrsMessage* msg, SrsOnMetaDataPacket* metadata) @@ -926,7 +920,8 @@ int SrsSource::on_meta_data(SrsMessage* msg, SrsOnMetaDataPacket* metadata)
926 std::vector<SrsConsumer*>::iterator it; 920 std::vector<SrsConsumer*>::iterator it;
927 for (it = consumers.begin(); it != consumers.end(); ++it) { 921 for (it = consumers.begin(); it != consumers.end(); ++it) {
928 SrsConsumer* consumer = *it; 922 SrsConsumer* consumer = *it;
929 - if ((ret = consumer->enqueue(cache_metadata->copy(), sample_rate, frame_rate)) != ERROR_SUCCESS) { 923 + SrsSharedPtrMessage* copy = cache_metadata->copy();
  924 + if ((ret = consumer->enqueue(copy, atc, sample_rate, frame_rate)) != ERROR_SUCCESS) {
930 srs_error("dispatch the metadata failed. ret=%d", ret); 925 srs_error("dispatch the metadata failed. ret=%d", ret);
931 return ret; 926 return ret;
932 } 927 }
@@ -987,17 +982,17 @@ int SrsSource::on_audio(SrsMessage* audio) @@ -987,17 +982,17 @@ int SrsSource::on_audio(SrsMessage* audio)
987 982
988 // copy to all consumer 983 // copy to all consumer
989 if (true) { 984 if (true) {
990 - std::vector<SrsConsumer*>::iterator it;  
991 - for (it = consumers.begin(); it != consumers.end(); ++it) {  
992 - SrsConsumer* consumer = *it;  
993 - if ((ret = consumer->enqueue(msg->copy(), sample_rate, frame_rate)) != ERROR_SUCCESS) { 985 + for (int i = 0; i < (int)consumers.size(); i++) {
  986 + SrsConsumer* consumer = consumers.at(i);
  987 + SrsSharedPtrMessage* copy = msg->copy();
  988 + if ((ret = consumer->enqueue(copy, atc, sample_rate, frame_rate)) != ERROR_SUCCESS) {
994 srs_error("dispatch the audio failed. ret=%d", ret); 989 srs_error("dispatch the audio failed. ret=%d", ret);
995 return ret; 990 return ret;
996 } 991 }
997 } 992 }
998 srs_info("dispatch audio success."); 993 srs_info("dispatch audio success.");
999 } 994 }
1000 - 995 +
1001 // copy to all forwarders. 996 // copy to all forwarders.
1002 if (true) { 997 if (true) {
1003 std::vector<SrsForwarder*>::iterator it; 998 std::vector<SrsForwarder*>::iterator it;
@@ -1077,10 +1072,10 @@ int SrsSource::on_video(SrsMessage* video) @@ -1077,10 +1072,10 @@ int SrsSource::on_video(SrsMessage* video)
1077 1072
1078 // copy to all consumer 1073 // copy to all consumer
1079 if (true) { 1074 if (true) {
1080 - std::vector<SrsConsumer*>::iterator it;  
1081 - for (it = consumers.begin(); it != consumers.end(); ++it) {  
1082 - SrsConsumer* consumer = *it;  
1083 - if ((ret = consumer->enqueue(msg->copy(), sample_rate, frame_rate)) != ERROR_SUCCESS) { 1075 + for (int i = 0; i < (int)consumers.size(); i++) {
  1076 + SrsConsumer* consumer = consumers.at(i);
  1077 + SrsSharedPtrMessage* copy = msg->copy();
  1078 + if ((ret = consumer->enqueue(copy, atc, sample_rate, frame_rate)) != ERROR_SUCCESS) {
1084 srs_error("dispatch the video failed. ret=%d", ret); 1079 srs_error("dispatch the video failed. ret=%d", ret);
1085 return ret; 1080 return ret;
1086 } 1081 }
@@ -1327,27 +1322,27 @@ void SrsSource::on_unpublish() @@ -1327,27 +1322,27 @@ void SrsSource::on_unpublish()
1327 } 1322 }
1328 1323
1329 // copy metadata. 1324 // copy metadata.
1330 - if (cache_metadata && (ret = consumer->enqueue(cache_metadata->copy(), sample_rate, frame_rate)) != ERROR_SUCCESS) { 1325 + if (cache_metadata && (ret = consumer->enqueue(cache_metadata->copy(), atc, sample_rate, frame_rate)) != ERROR_SUCCESS) {
1331 srs_error("dispatch metadata failed. ret=%d", ret); 1326 srs_error("dispatch metadata failed. ret=%d", ret);
1332 return ret; 1327 return ret;
1333 } 1328 }
1334 srs_info("dispatch metadata success"); 1329 srs_info("dispatch metadata success");
1335 1330
1336 // copy sequence header 1331 // copy sequence header
1337 - if (cache_sh_video && (ret = consumer->enqueue(cache_sh_video->copy(), sample_rate, frame_rate)) != ERROR_SUCCESS) { 1332 + if (cache_sh_video && (ret = consumer->enqueue(cache_sh_video->copy(), atc, sample_rate, frame_rate)) != ERROR_SUCCESS) {
1338 srs_error("dispatch video sequence header failed. ret=%d", ret); 1333 srs_error("dispatch video sequence header failed. ret=%d", ret);
1339 return ret; 1334 return ret;
1340 } 1335 }
1341 srs_info("dispatch video sequence header success"); 1336 srs_info("dispatch video sequence header success");
1342 1337
1343 - if (cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio->copy(), sample_rate, frame_rate)) != ERROR_SUCCESS) { 1338 + if (cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio->copy(), atc, sample_rate, frame_rate)) != ERROR_SUCCESS) {
1344 srs_error("dispatch audio sequence header failed. ret=%d", ret); 1339 srs_error("dispatch audio sequence header failed. ret=%d", ret);
1345 return ret; 1340 return ret;
1346 } 1341 }
1347 srs_info("dispatch audio sequence header success"); 1342 srs_info("dispatch audio sequence header success");
1348 1343
1349 // copy gop cache to client. 1344 // copy gop cache to client.
1350 - if ((ret = gop_cache->dump(consumer, sample_rate, frame_rate)) != ERROR_SUCCESS) { 1345 + if ((ret = gop_cache->dump(consumer, atc, sample_rate, frame_rate)) != ERROR_SUCCESS) {
1351 return ret; 1346 return ret;
1352 } 1347 }
1353 1348
@@ -1375,11 +1370,6 @@ void SrsSource::set_cache(bool enabled) @@ -1375,11 +1370,6 @@ void SrsSource::set_cache(bool enabled)
1375 gop_cache->set(enabled); 1370 gop_cache->set(enabled);
1376 } 1371 }
1377 1372
1378 -bool SrsSource::is_atc()  
1379 -{  
1380 - return atc;  
1381 -}  
1382 -  
1383 int SrsSource::on_edge_start_play() 1373 int SrsSource::on_edge_start_play()
1384 { 1374 {
1385 return play_edge->on_client_play(); 1375 return play_edge->on_client_play();
@@ -110,11 +110,11 @@ public: @@ -110,11 +110,11 @@ public:
110 virtual int enqueue(SrsSharedPtrMessage* msg); 110 virtual int enqueue(SrsSharedPtrMessage* msg);
111 /** 111 /**
112 * get packets in consumer queue. 112 * get packets in consumer queue.
113 - * @pmsgs SrsMessages*[], output the prt array.  
114 - * @count the count in array.  
115 - * @max_count the max count to dequeue, 0 to dequeue all. 113 + * @pmsgs SrsMessages*[], used to store the msgs, user must alloc it.
  114 + * @count the count in array, output param.
  115 + * @max_count the max count to dequeue, must be positive.
116 */ 116 */
117 - virtual int get_packets(int max_count, SrsSharedPtrMessage**& pmsgs, int& count); 117 + virtual int dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count);
118 private: 118 private:
119 /** 119 /**
120 * remove a gop from the front. 120 * remove a gop from the front.
@@ -155,19 +155,20 @@ public: @@ -155,19 +155,20 @@ public:
155 virtual int get_time(); 155 virtual int get_time();
156 /** 156 /**
157 * enqueue an shared ptr message. 157 * enqueue an shared ptr message.
  158 + * @param whether atc, donot use jitter correct if true.
158 * @param tba timebase of audio. 159 * @param tba timebase of audio.
159 * used to calc the audio time delta if time-jitter detected. 160 * used to calc the audio time delta if time-jitter detected.
160 * @param tbv timebase of video. 161 * @param tbv timebase of video.
161 * used to calc the video time delta if time-jitter detected. 162 * used to calc the video time delta if time-jitter detected.
162 */ 163 */
163 - virtual int enqueue(SrsSharedPtrMessage* msg, int tba, int tbv); 164 + virtual int enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv);
164 /** 165 /**
165 * get packets in consumer queue. 166 * get packets in consumer queue.
166 - * @pmsgs SrsMessages*[], output the prt array.  
167 - * @count the count in array.  
168 - * @max_count the max count to dequeue, 0 to dequeue all. 167 + * @pmsgs SrsMessages*[], used to store the msgs, user must alloc it.
  168 + * @count the count in array, output param.
  169 + * @max_count the max count to dequeue, must be positive.
169 */ 170 */
170 - virtual int get_packets(int max_count, SrsSharedPtrMessage**& pmsgs, int& count); 171 + virtual int dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count);
171 /** 172 /**
172 * when client send the pause message. 173 * when client send the pause message.
173 */ 174 */
@@ -208,7 +209,7 @@ public: @@ -208,7 +209,7 @@ public:
208 */ 209 */
209 virtual int cache(SrsSharedPtrMessage* msg); 210 virtual int cache(SrsSharedPtrMessage* msg);
210 virtual void clear(); 211 virtual void clear();
211 - virtual int dump(SrsConsumer* consumer, int tba, int tbv); 212 + virtual int dump(SrsConsumer* consumer, bool atc, int tba, int tbv);
212 /** 213 /**
213 * used for atc to get the time of gop cache, 214 * used for atc to get the time of gop cache,
214 * the atc will adjust the sequence header timestamp to gop cache. 215 * the atc will adjust the sequence header timestamp to gop cache.
@@ -346,8 +347,6 @@ public: @@ -346,8 +347,6 @@ public:
346 virtual void set_cache(bool enabled); 347 virtual void set_cache(bool enabled);
347 // internal 348 // internal
348 public: 349 public:
349 - // for consumer, atc feature.  
350 - virtual bool is_atc();  
351 // for edge, when play edge stream, check the state 350 // for edge, when play edge stream, check the state
352 virtual int on_edge_start_play(); 351 virtual int on_edge_start_play();
353 // for edge, when publish edge stream, check the state 352 // for edge, when publish edge stream, check the state
@@ -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 "129" 34 +#define VERSION_REVISION "130"
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"
@@ -66,53 +66,4 @@ public: @@ -66,53 +66,4 @@ public:
66 } 66 }
67 }; 67 };
68 68
69 -/**  
70 -* auto free the array ptrs, for example, MyClass* msgs[10],  
71 -* which stores 10 MyClass* objects, this class will:  
72 -* 1. free each MyClass* in array.  
73 -* 2. free the msgs itself.  
74 -* 3. set msgs to NULL.  
75 -* @remark, MyClass* msgs[] equals to MyClass**, the ptr array equals ptr to ptr.  
76 -* Usage:  
77 -* MyClass* msgs[10];  
78 -* // ...... use msgs.  
79 -* SrsAutoFreeArray(MyClass, msgs, 10);  
80 -*/  
81 -#define SrsAutoFreeArray(className, instance, size) \  
82 - __SrsAutoFreeArray<className> _auto_free_array_##instance(&instance, size)  
83 -template<class T>  
84 -class __SrsAutoFreeArray  
85 -{  
86 -private:  
87 - T*** ptr;  
88 - int size;  
89 -public:  
90 - /**  
91 - * auto delete the ptr array.  
92 - */  
93 - __SrsAutoFreeArray(T*** _ptr, int _size) {  
94 - ptr = _ptr;  
95 - size = _size;  
96 - }  
97 -  
98 - virtual ~__SrsAutoFreeArray() {  
99 - if (ptr == NULL || *ptr == NULL) {  
100 - return;  
101 - }  
102 -  
103 - T** arr = *ptr;  
104 - for (int i = 0; i < size; i++) {  
105 - T* pobj = arr[i];  
106 - if (pobj) {  
107 - delete pobj;  
108 - arr[i] = NULL;  
109 - }  
110 - }  
111 -  
112 - delete arr;  
113 -  
114 - *ptr = NULL;  
115 - }  
116 -};  
117 -  
118 #endif 69 #endif
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013-2014 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_protocol_msg_array.hpp>
  25 +
  26 +#include <srs_protocol_rtmp_stack.hpp>
  27 +
  28 +SrsSharedPtrMessageArray::SrsSharedPtrMessageArray(int _size)
  29 +{
  30 + srs_assert(_size > 0);
  31 +
  32 + msgs = new SrsSharedPtrMessage*[_size];
  33 + size = _size;
  34 +
  35 + // initialize
  36 + for (int i = 0; i < _size; i++) {
  37 + msgs[i] = NULL;
  38 + }
  39 +}
  40 +
  41 +SrsSharedPtrMessageArray::~SrsSharedPtrMessageArray()
  42 +{
  43 + // cleanup
  44 + for (int i = 0; i < size; i++) {
  45 + SrsSharedPtrMessage* msg = msgs[i];
  46 + srs_freep(msg);
  47 + }
  48 +
  49 + srs_freep(msgs);
  50 +}
  51 +
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013-2014 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#ifndef SRS_RTMP_PROTOCOL_MSG_ARRAY_HPP
  25 +#define SRS_RTMP_PROTOCOL_MSG_ARRAY_HPP
  26 +
  27 +/*
  28 +#include <srs_protocol_msg_array.hpp>
  29 +*/
  30 +
  31 +#include <srs_core.hpp>
  32 +
  33 +class SrsSharedPtrMessage;
  34 +
  35 +/**
  36 +* the class to auto free the shared ptr message array.
  37 +*/
  38 +class SrsSharedPtrMessageArray
  39 +{
  40 +public:
  41 + /**
  42 + * when user already send the msg in msgs, please set to NULL,
  43 + * for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg),
  44 + * where send(msg) will always send and free it.
  45 + */
  46 + SrsSharedPtrMessage** msgs;
  47 + int size;
  48 +public:
  49 + SrsSharedPtrMessageArray(int _size);
  50 + virtual ~SrsSharedPtrMessageArray();
  51 +};
  52 +
  53 +#endif
@@ -437,13 +437,12 @@ int SrsProtocol::decode_message(SrsMessage* msg, SrsPacket** ppacket) @@ -437,13 +437,12 @@ int SrsProtocol::decode_message(SrsMessage* msg, SrsPacket** ppacket)
437 return ret; 437 return ret;
438 } 438 }
439 439
440 -int SrsProtocol::do_send_and_free_message(SrsMessage* msg, SrsPacket* packet) 440 +int SrsProtocol::do_send_message(SrsMessage* msg, SrsPacket* packet)
441 { 441 {
442 int ret = ERROR_SUCCESS; 442 int ret = ERROR_SUCCESS;
443 443
444 - // always free msg. 444 + // always not NULL msg.
445 srs_assert(msg); 445 srs_assert(msg);
446 - SrsAutoFree(SrsMessage, msg);  
447 446
448 // we donot use the complex basic header, 447 // we donot use the complex basic header,
449 // ensure the basic header is 1bytes. 448 // ensure the basic header is 1bytes.
@@ -497,7 +496,7 @@ int SrsProtocol::do_send_and_free_message(SrsMessage* msg, SrsPacket* packet) @@ -497,7 +496,7 @@ int SrsProtocol::do_send_and_free_message(SrsMessage* msg, SrsPacket* packet)
497 *pheader++ = pp[3]; 496 *pheader++ = pp[3];
498 497
499 // chunk extended timestamp header, 0 or 4 bytes, big-endian 498 // chunk extended timestamp header, 0 or 4 bytes, big-endian
500 - if(timestamp >= RTMP_EXTENDED_TIMESTAMP){ 499 + if(timestamp >= RTMP_EXTENDED_TIMESTAMP) {
501 pp = (char*)&timestamp; 500 pp = (char*)&timestamp;
502 *pheader++ = pp[3]; 501 *pheader++ = pp[3];
503 *pheader++ = pp[2]; 502 *pheader++ = pp[2];
@@ -522,7 +521,7 @@ int SrsProtocol::do_send_and_free_message(SrsMessage* msg, SrsPacket* packet) @@ -522,7 +521,7 @@ int SrsProtocol::do_send_and_free_message(SrsMessage* msg, SrsPacket* packet)
522 // @see: ngx_rtmp_prepare_message 521 // @see: ngx_rtmp_prepare_message
523 // @see: http://blog.csdn.net/win_lin/article/details/13363699 522 // @see: http://blog.csdn.net/win_lin/article/details/13363699
524 u_int32_t timestamp = (u_int32_t)msg->header.timestamp; 523 u_int32_t timestamp = (u_int32_t)msg->header.timestamp;
525 - if(timestamp >= RTMP_EXTENDED_TIMESTAMP){ 524 + if (timestamp >= RTMP_EXTENDED_TIMESTAMP) {
526 pp = (char*)&timestamp; 525 pp = (char*)&timestamp;
527 *pheader++ = pp[3]; 526 *pheader++ = pp[3];
528 *pheader++ = pp[2]; 527 *pheader++ = pp[2];
@@ -733,7 +732,12 @@ int SrsProtocol::send_and_free_message(SrsMessage* msg, int stream_id) @@ -733,7 +732,12 @@ int SrsProtocol::send_and_free_message(SrsMessage* msg, int stream_id)
733 if (msg) { 732 if (msg) {
734 msg->header.stream_id = stream_id; 733 msg->header.stream_id = stream_id;
735 } 734 }
736 - return do_send_and_free_message(msg, NULL); 735 +
  736 + // donot use the auto free to free the msg,
  737 + // for performance issue.
  738 + int ret = do_send_message(msg, NULL);
  739 + srs_freep(msg);
  740 + return ret;
737 } 741 }
738 742
739 int SrsProtocol::send_and_free_packet(SrsPacket* packet, int stream_id) 743 int SrsProtocol::send_and_free_packet(SrsPacket* packet, int stream_id)
@@ -767,9 +771,10 @@ int SrsProtocol::send_and_free_packet(SrsPacket* packet, int stream_id) @@ -767,9 +771,10 @@ int SrsProtocol::send_and_free_packet(SrsPacket* packet, int stream_id)
767 msg->header.stream_id = stream_id; 771 msg->header.stream_id = stream_id;
768 msg->header.perfer_cid = packet->get_perfer_cid(); 772 msg->header.perfer_cid = packet->get_perfer_cid();
769 773
770 - if ((ret = do_send_and_free_message(msg, packet)) != ERROR_SUCCESS) {  
771 - return ret;  
772 - } 774 + // donot use the auto free to free the msg,
  775 + // for performance issue.
  776 + ret = do_send_message(msg, packet);
  777 + srs_freep(msg);
773 778
774 return ret; 779 return ret;
775 } 780 }
@@ -174,10 +174,10 @@ public: @@ -174,10 +174,10 @@ public:
174 virtual int send_and_free_packet(SrsPacket* packet, int stream_id); 174 virtual int send_and_free_packet(SrsPacket* packet, int stream_id);
175 private: 175 private:
176 /** 176 /**
177 - * imp for send_and_free_message 177 + * send out the message, donot free it, the caller must free the param msg.
178 * @param packet the packet of message, NULL for raw message. 178 * @param packet the packet of message, NULL for raw message.
179 */ 179 */
180 - virtual int do_send_and_free_message(SrsMessage* msg, SrsPacket* packet); 180 + virtual int do_send_message(SrsMessage* msg, SrsPacket* packet);
181 /** 181 /**
182 * imp for decode_message 182 * imp for decode_message
183 */ 183 */
@@ -36,6 +36,8 @@ file @@ -36,6 +36,8 @@ file
36 ..\rtmp\srs_protocol_handshake.cpp, 36 ..\rtmp\srs_protocol_handshake.cpp,
37 ..\rtmp\srs_protocol_io.hpp, 37 ..\rtmp\srs_protocol_io.hpp,
38 ..\rtmp\srs_protocol_io.cpp, 38 ..\rtmp\srs_protocol_io.cpp,
  39 + ..\rtmp\srs_protocol_msg_array.hpp,
  40 + ..\rtmp\srs_protocol_msg_array.cpp,
39 ..\rtmp\srs_protocol_rtmp.hpp, 41 ..\rtmp\srs_protocol_rtmp.hpp,
40 ..\rtmp\srs_protocol_rtmp.cpp, 42 ..\rtmp\srs_protocol_rtmp.cpp,
41 ..\rtmp\srs_protocol_rtmp_stack.hpp, 43 ..\rtmp\srs_protocol_rtmp_stack.hpp,