winlin

use send_min_interval for stream control. 2.0.183

@@ -342,6 +342,7 @@ Remark: @@ -342,6 +342,7 @@ Remark:
342 342
343 ## History 343 ## History
344 344
  345 +* v2.0, 2015-08-14, use send_min_interval for stream control. 2.0.183
345 * v2.0, 2015-08-12, enable the SRS_PERF_TCP_NODELAY and add config tcp_nodelay. 2.0.182 346 * v2.0, 2015-08-12, enable the SRS_PERF_TCP_NODELAY and add config tcp_nodelay. 2.0.182
346 * v2.0, 2015-08-11, for [#442](https://github.com/simple-rtmp-server/srs/issues/442) support kickoff connected client. 2.0.181 347 * v2.0, 2015-08-11, for [#442](https://github.com/simple-rtmp-server/srs/issues/442) support kickoff connected client. 2.0.181
347 * v2.0, 2015-07-21, for [#169](https://github.com/simple-rtmp-server/srs/issues/169) support default values for transcode. 2.0.180 348 * v2.0, 2015-07-21, for [#169](https://github.com/simple-rtmp-server/srs/issues/169) support default values for transcode. 2.0.180
@@ -858,6 +858,27 @@ vhost min.delay.com { @@ -858,6 +858,27 @@ vhost min.delay.com {
858 tcp_nodelay on; 858 tcp_nodelay on;
859 } 859 }
860 860
  861 +# the vhost to control the stream delivery feature
  862 +vhost stream.control.com {
  863 + # @see vhost mrw.srs.com for detail.
  864 + min_latency on;
  865 + mr {
  866 + enabled off;
  867 + }
  868 + mw_latency 100;
  869 + # @see vhost min.delay.com
  870 + queue_length 10;
  871 + tcp_nodelay on;
  872 + # the minimal packets send interval in ms,
  873 + # used to control the ndiff of stream by srs_rtmp_dump,
  874 + # for example, some device can only accept some stream which
  875 + # delivery packets in constant interval(not cbr).
  876 + # @remark 0 to disable the minimal interval.
  877 + # @remark >0 to make the srs to send message one by one.
  878 + # default: 0
  879 + send_min_interval 3;
  880 +}
  881 +
861 # the vhost for antisuck. 882 # the vhost for antisuck.
862 vhost refer.anti_suck.com { 883 vhost refer.anti_suck.com {
863 # the common refer for play and publish. 884 # the common refer for play and publish.
@@ -257,6 +257,7 @@ int main(int argc, char** argv) @@ -257,6 +257,7 @@ int main(int argc, char** argv)
257 } 257 }
258 258
259 u_int32_t pre_timestamp = 0; 259 u_int32_t pre_timestamp = 0;
  260 + int64_t pre_now = srs_utils_time_ms();
260 for (;;) { 261 for (;;) {
261 int size; 262 int size;
262 char type; 263 char type;
@@ -268,11 +269,12 @@ int main(int argc, char** argv) @@ -268,11 +269,12 @@ int main(int argc, char** argv)
268 goto rtmp_destroy; 269 goto rtmp_destroy;
269 } 270 }
270 271
271 - if (srs_human_print_rtmp_packet2(type, timestamp, data, size, pre_timestamp) != 0) { 272 + if (srs_human_print_rtmp_packet3(type, timestamp, data, size, pre_timestamp, pre_now) != 0) {
272 srs_human_trace("print rtmp packet failed."); 273 srs_human_trace("print rtmp packet failed.");
273 goto rtmp_destroy; 274 goto rtmp_destroy;
274 } 275 }
275 pre_timestamp = timestamp; 276 pre_timestamp = timestamp;
  277 + pre_now = srs_utils_time_ms();
276 278
277 // we only write some types of messages to flv file. 279 // we only write some types of messages to flv file.
278 int is_flv_msg = type == SRS_RTMP_TYPE_AUDIO 280 int is_flv_msg = type == SRS_RTMP_TYPE_AUDIO
@@ -757,6 +757,17 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) @@ -757,6 +757,17 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root)
757 } 757 }
758 srs_trace("vhost %s reload mw success.", vhost.c_str()); 758 srs_trace("vhost %s reload mw success.", vhost.c_str());
759 } 759 }
  760 + // smi(send_min_interval), only one per vhost
  761 + if (!srs_directive_equals(new_vhost->get("send_min_interval"), old_vhost->get("send_min_interval"))) {
  762 + for (it = subscribes.begin(); it != subscribes.end(); ++it) {
  763 + ISrsReloadHandler* subscribe = *it;
  764 + if ((ret = subscribe->on_reload_vhost_smi(vhost)) != ERROR_SUCCESS) {
  765 + srs_error("vhost %s notify subscribes smi failed. ret=%d", vhost.c_str(), ret);
  766 + return ret;
  767 + }
  768 + }
  769 + srs_trace("vhost %s reload smi success.", vhost.c_str());
  770 + }
760 // min_latency, only one per vhost 771 // min_latency, only one per vhost
761 if (!srs_directive_equals(new_vhost->get("min_latency"), old_vhost->get("min_latency"))) { 772 if (!srs_directive_equals(new_vhost->get("min_latency"), old_vhost->get("min_latency"))) {
762 for (it = subscribes.begin(); it != subscribes.end(); ++it) { 773 for (it = subscribes.begin(); it != subscribes.end(); ++it) {
@@ -1750,7 +1761,7 @@ int SrsConfig::check_config() @@ -1750,7 +1761,7 @@ int SrsConfig::check_config()
1750 && n != "time_jitter" && n != "mix_correct" 1761 && n != "time_jitter" && n != "mix_correct"
1751 && n != "atc" && n != "atc_auto" 1762 && n != "atc" && n != "atc_auto"
1752 && n != "debug_srs_upnode" 1763 && n != "debug_srs_upnode"
1753 - && n != "mr" && n != "mw_latency" && n != "min_latency" && n != "tcp_nodelay" 1764 + && n != "mr" && n != "mw_latency" && n != "min_latency" && n != "tcp_nodelay" && n != "send_min_interval"
1754 && n != "security" && n != "http_remux" 1765 && n != "security" && n != "http_remux"
1755 && n != "http" && n != "http_static" 1766 && n != "http" && n != "http_static"
1756 && n != "hds" 1767 && n != "hds"
@@ -2506,6 +2517,23 @@ bool SrsConfig::get_tcp_nodelay(string vhost) @@ -2506,6 +2517,23 @@ bool SrsConfig::get_tcp_nodelay(string vhost)
2506 return SRS_CONF_PERFER_FALSE(conf->arg0()); 2517 return SRS_CONF_PERFER_FALSE(conf->arg0());
2507 } 2518 }
2508 2519
  2520 +int SrsConfig::get_send_min_interval(string vhost)
  2521 +{
  2522 + static int DEFAULT = 0;
  2523 +
  2524 + SrsConfDirective* conf = get_vhost(vhost);
  2525 + if (!conf) {
  2526 + return DEFAULT;
  2527 + }
  2528 +
  2529 + conf = conf->get("send_min_interval");
  2530 + if (!conf || conf->arg0().empty()) {
  2531 + return DEFAULT;
  2532 + }
  2533 +
  2534 + return ::atoi(conf->arg0().c_str());
  2535 +}
  2536 +
2509 int SrsConfig::get_global_chunk_size() 2537 int SrsConfig::get_global_chunk_size()
2510 { 2538 {
2511 SrsConfDirective* conf = root->get("chunk_size"); 2539 SrsConfDirective* conf = root->get("chunk_size");
@@ -526,6 +526,10 @@ public: @@ -526,6 +526,10 @@ public:
526 * whether enable tcp nodelay for all clients of vhost. 526 * whether enable tcp nodelay for all clients of vhost.
527 */ 527 */
528 virtual bool get_tcp_nodelay(std::string vhost); 528 virtual bool get_tcp_nodelay(std::string vhost);
  529 + /**
  530 + * the minimal send interval in ms.
  531 + */
  532 + virtual int get_send_min_interval(std::string vhost);
529 private: 533 private:
530 /** 534 /**
531 * get the global chunk size. 535 * get the global chunk size.
@@ -170,6 +170,11 @@ int ISrsReloadHandler::on_reload_vhost_mw(string /*vhost*/) @@ -170,6 +170,11 @@ int ISrsReloadHandler::on_reload_vhost_mw(string /*vhost*/)
170 return ERROR_SUCCESS; 170 return ERROR_SUCCESS;
171 } 171 }
172 172
  173 +int ISrsReloadHandler::on_reload_vhost_smi(string /*vhost*/)
  174 +{
  175 + return ERROR_SUCCESS;
  176 +}
  177 +
173 int ISrsReloadHandler::on_reload_vhost_realtime(string /*vhost*/) 178 int ISrsReloadHandler::on_reload_vhost_realtime(string /*vhost*/)
174 { 179 {
175 return ERROR_SUCCESS; 180 return ERROR_SUCCESS;
@@ -73,6 +73,7 @@ public: @@ -73,6 +73,7 @@ public:
73 virtual int on_reload_vhost_dvr(std::string vhost); 73 virtual int on_reload_vhost_dvr(std::string vhost);
74 virtual int on_reload_vhost_mr(std::string vhost); 74 virtual int on_reload_vhost_mr(std::string vhost);
75 virtual int on_reload_vhost_mw(std::string vhost); 75 virtual int on_reload_vhost_mw(std::string vhost);
  76 + virtual int on_reload_vhost_smi(std::string vhost);
76 virtual int on_reload_vhost_realtime(std::string vhost); 77 virtual int on_reload_vhost_realtime(std::string vhost);
77 virtual int on_reload_vhost_chunk_size(std::string vhost); 78 virtual int on_reload_vhost_chunk_size(std::string vhost);
78 virtual int on_reload_vhost_transcode(std::string vhost); 79 virtual int on_reload_vhost_transcode(std::string vhost);
@@ -93,6 +93,7 @@ SrsRtmpConn::SrsRtmpConn(SrsServer* svr, st_netfd_t c) @@ -93,6 +93,7 @@ SrsRtmpConn::SrsRtmpConn(SrsServer* svr, st_netfd_t c)
93 mw_sleep = SRS_PERF_MW_SLEEP; 93 mw_sleep = SRS_PERF_MW_SLEEP;
94 mw_enabled = false; 94 mw_enabled = false;
95 realtime = SRS_PERF_MIN_LATENCY_ENABLED; 95 realtime = SRS_PERF_MIN_LATENCY_ENABLED;
  96 + send_min_interval = 0;
96 97
97 _srs_config->subscribe(this); 98 _srs_config->subscribe(this);
98 } 99 }
@@ -247,6 +248,23 @@ int SrsRtmpConn::on_reload_vhost_mw(string vhost) @@ -247,6 +248,23 @@ int SrsRtmpConn::on_reload_vhost_mw(string vhost)
247 return ret; 248 return ret;
248 } 249 }
249 250
  251 +int SrsRtmpConn::on_reload_vhost_smi(string vhost)
  252 +{
  253 + int ret = ERROR_SUCCESS;
  254 +
  255 + if (req->vhost != vhost) {
  256 + return ret;
  257 + }
  258 +
  259 + int smi = _srs_config->get_send_min_interval(vhost);
  260 + if (smi != send_min_interval) {
  261 + srs_trace("apply smi %d=>%d", send_min_interval, smi);
  262 + send_min_interval = smi;
  263 + }
  264 +
  265 + return ret;
  266 +}
  267 +
250 int SrsRtmpConn::on_reload_vhost_realtime(string vhost) 268 int SrsRtmpConn::on_reload_vhost_realtime(string vhost)
251 { 269 {
252 int ret = ERROR_SUCCESS; 270 int ret = ERROR_SUCCESS;
@@ -589,10 +607,15 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe @@ -589,10 +607,15 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe
589 // when mw_sleep changed, resize the socket send buffer. 607 // when mw_sleep changed, resize the socket send buffer.
590 mw_enabled = true; 608 mw_enabled = true;
591 change_mw_sleep(_srs_config->get_mw_sleep_ms(req->vhost)); 609 change_mw_sleep(_srs_config->get_mw_sleep_ms(req->vhost));
  610 + // initialize the send_min_interval
  611 + send_min_interval = _srs_config->get_send_min_interval(req->vhost);
592 612
593 // set the sock options. 613 // set the sock options.
594 set_sock_options(); 614 set_sock_options();
595 615
  616 + srs_trace("start play smi=%d, mw_sleep=%d, mw_enabled=%d, realtime=%d",
  617 + send_min_interval, mw_sleep, mw_enabled, realtime);
  618 +
596 while (!disposed) { 619 while (!disposed) {
597 // collect elapse for pithy print. 620 // collect elapse for pithy print.
598 pprint->elapse(); 621 pprint->elapse();
@@ -641,7 +664,8 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe @@ -641,7 +664,8 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe
641 664
642 // get messages from consumer. 665 // get messages from consumer.
643 // each msg in msgs.msgs must be free, for the SrsMessageArray never free them. 666 // each msg in msgs.msgs must be free, for the SrsMessageArray never free them.
644 - int count = 0; 667 + // @remark when enable send_min_interval, only fetch one message a time.
  668 + int count = send_min_interval? 1 : 0;
645 if ((ret = consumer->dump_packets(&msgs, count)) != ERROR_SUCCESS) { 669 if ((ret = consumer->dump_packets(&msgs, count)) != ERROR_SUCCESS) {
646 srs_error("get messages from consumer failed. ret=%d", ret); 670 srs_error("get messages from consumer failed. ret=%d", ret);
647 return ret; 671 return ret;
@@ -716,6 +740,11 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe @@ -716,6 +740,11 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe
716 return ret; 740 return ret;
717 } 741 }
718 } 742 }
  743 +
  744 + // apply the minimal interval for delivery stream in ms.
  745 + if (send_min_interval > 0) {
  746 + st_usleep(send_min_interval * 1000);
  747 + }
719 } 748 }
720 749
721 return ret; 750 return ret;
@@ -85,6 +85,8 @@ private: @@ -85,6 +85,8 @@ private:
85 // for realtime 85 // for realtime
86 // @see https://github.com/simple-rtmp-server/srs/issues/257 86 // @see https://github.com/simple-rtmp-server/srs/issues/257
87 bool realtime; 87 bool realtime;
  88 + // the minimal interval in ms for delivery stream.
  89 + int send_min_interval;
88 public: 90 public:
89 SrsRtmpConn(SrsServer* svr, st_netfd_t c); 91 SrsRtmpConn(SrsServer* svr, st_netfd_t c);
90 virtual ~SrsRtmpConn(); 92 virtual ~SrsRtmpConn();
@@ -96,6 +98,7 @@ protected: @@ -96,6 +98,7 @@ protected:
96 public: 98 public:
97 virtual int on_reload_vhost_removed(std::string vhost); 99 virtual int on_reload_vhost_removed(std::string vhost);
98 virtual int on_reload_vhost_mw(std::string vhost); 100 virtual int on_reload_vhost_mw(std::string vhost);
  101 + virtual int on_reload_vhost_smi(std::string vhost);
99 virtual int on_reload_vhost_realtime(std::string vhost); 102 virtual int on_reload_vhost_realtime(std::string vhost);
100 // interface IKbpsDelta 103 // interface IKbpsDelta
101 public: 104 public:
@@ -301,7 +301,8 @@ int SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, in @@ -301,7 +301,8 @@ int SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, in
301 } 301 }
302 302
303 srs_assert(max_count > 0); 303 srs_assert(max_count > 0);
304 - count = srs_min(max_count, nb_msgs); 304 + // when count is 0, dumps all; otherwise, dumps no more than count.
  305 + count = srs_min(max_count, count? count : nb_msgs);
305 306
306 SrsSharedPtrMessage** omsgs = msgs.data(); 307 SrsSharedPtrMessage** omsgs = msgs.data();
307 for (int i = 0; i < count; i++) { 308 for (int i = 0; i < count; i++) {
@@ -173,11 +173,12 @@ public: @@ -173,11 +173,12 @@ public:
173 */ 173 */
174 virtual int enqueue(SrsSharedPtrMessage* msg, bool* is_overflow = NULL); 174 virtual int enqueue(SrsSharedPtrMessage* msg, bool* is_overflow = NULL);
175 /** 175 /**
176 - * get packets in consumer queue.  
177 - * @pmsgs SrsSharedPtrMessage*[], used to store the msgs, user must alloc it.  
178 - * @count the count in array, output param.  
179 - * @max_count the max count to dequeue, must be positive.  
180 - */ 176 + * get packets in consumer queue.
  177 + * @pmsgs SrsSharedPtrMessage*[], used to store the msgs, user must alloc it.
  178 + * @count the count in array, input and output param.
  179 + * @max_count the max count to dequeue, must be positive.
  180 + * @remark user can specifies the count to get specified msgs; 0 to get all if possible.
  181 + */
181 virtual int dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count); 182 virtual int dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count);
182 /** 183 /**
183 * dumps packets to consumer, use specified args. 184 * dumps packets to consumer, use specified args.
@@ -256,10 +257,11 @@ public: @@ -256,10 +257,11 @@ public:
256 */ 257 */
257 virtual int enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag); 258 virtual int enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag);
258 /** 259 /**
259 - * get packets in consumer queue.  
260 - * @param msgs the msgs array to dump packets to send.  
261 - * @param count the count in array, output param.  
262 - */ 260 + * get packets in consumer queue.
  261 + * @param msgs the msgs array to dump packets to send.
  262 + * @param count the count in array, intput and output param.
  263 + * @remark user can specifies the count to get specified msgs; 0 to get all if possible.
  264 + */
263 virtual int dump_packets(SrsMessageArray* msgs, int& count); 265 virtual int dump_packets(SrsMessageArray* msgs, int& count);
264 #ifdef SRS_PERF_QUEUE_COND_WAIT 266 #ifdef SRS_PERF_QUEUE_COND_WAIT
265 /** 267 /**
@@ -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 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 182 34 +#define VERSION_REVISION 183
35 35
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "SRS" 37 #define RTMP_SIG_SRS_KEY "SRS"
@@ -1915,8 +1915,7 @@ void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value) @@ -1915,8 +1915,7 @@ void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value)
1915 1915
1916 int64_t srs_utils_time_ms() 1916 int64_t srs_utils_time_ms()
1917 { 1917 {
1918 - srs_update_system_time_ms();  
1919 - return srs_get_system_time_ms(); 1918 + return srs_update_system_time_ms();
1920 } 1919 }
1921 1920
1922 int64_t srs_utils_send_bytes(srs_rtmp_t rtmp) 1921 int64_t srs_utils_send_bytes(srs_rtmp_t rtmp)
@@ -2321,6 +2320,11 @@ int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int @@ -2321,6 +2320,11 @@ int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int
2321 2320
2322 int srs_human_print_rtmp_packet2(char type, u_int32_t timestamp, char* data, int size, u_int32_t pre_timestamp) 2321 int srs_human_print_rtmp_packet2(char type, u_int32_t timestamp, char* data, int size, u_int32_t pre_timestamp)
2323 { 2322 {
  2323 + return srs_human_print_rtmp_packet3(type, timestamp, data, size, pre_timestamp, 0);
  2324 +}
  2325 +
  2326 +int srs_human_print_rtmp_packet3(char type, u_int32_t timestamp, char* data, int size, u_int32_t pre_timestamp, int64_t pre_now)
  2327 +{
2324 int ret = ERROR_SUCCESS; 2328 int ret = ERROR_SUCCESS;
2325 2329
2326 int diff = 0; 2330 int diff = 0;
@@ -2328,24 +2332,29 @@ int srs_human_print_rtmp_packet2(char type, u_int32_t timestamp, char* data, int @@ -2328,24 +2332,29 @@ int srs_human_print_rtmp_packet2(char type, u_int32_t timestamp, char* data, int
2328 diff = (int)timestamp - (int)pre_timestamp; 2332 diff = (int)timestamp - (int)pre_timestamp;
2329 } 2333 }
2330 2334
  2335 + int ndiff = 0;
  2336 + if (pre_now > 0) {
  2337 + ndiff = (int)(srs_utils_time_ms() - pre_now);
  2338 + }
  2339 +
2331 u_int32_t pts; 2340 u_int32_t pts;
2332 if (srs_utils_parse_timestamp(timestamp, type, data, size, &pts) != 0) { 2341 if (srs_utils_parse_timestamp(timestamp, type, data, size, &pts) != 0) {
2333 - srs_human_trace("Rtmp packet type=%s, dts=%d, diff=%d, size=%d, DecodeError",  
2334 - srs_human_flv_tag_type2string(type), timestamp, diff, size 2342 + srs_human_trace("Rtmp packet type=%s, dts=%d, diff=%d, ndiff=%d, size=%d, DecodeError",
  2343 + srs_human_flv_tag_type2string(type), timestamp, diff, ndiff, size
2335 ); 2344 );
2336 return ret; 2345 return ret;
2337 } 2346 }
2338 2347
2339 if (type == SRS_RTMP_TYPE_VIDEO) { 2348 if (type == SRS_RTMP_TYPE_VIDEO) {
2340 - srs_human_trace("Video packet type=%s, dts=%d, pts=%d, diff=%d, size=%d, %s(%s,%s)",  
2341 - srs_human_flv_tag_type2string(type), timestamp, pts, diff, size, 2349 + srs_human_trace("Video packet type=%s, dts=%d, pts=%d, diff=%d, ndiff=%d, size=%d, %s(%s,%s)",
  2350 + srs_human_flv_tag_type2string(type), timestamp, pts, diff, ndiff, size,
2342 srs_human_flv_video_codec_id2string(srs_utils_flv_video_codec_id(data, size)), 2351 srs_human_flv_video_codec_id2string(srs_utils_flv_video_codec_id(data, size)),
2343 srs_human_flv_video_avc_packet_type2string(srs_utils_flv_video_avc_packet_type(data, size)), 2352 srs_human_flv_video_avc_packet_type2string(srs_utils_flv_video_avc_packet_type(data, size)),
2344 srs_human_flv_video_frame_type2string(srs_utils_flv_video_frame_type(data, size)) 2353 srs_human_flv_video_frame_type2string(srs_utils_flv_video_frame_type(data, size))
2345 ); 2354 );
2346 } else if (type == SRS_RTMP_TYPE_AUDIO) { 2355 } else if (type == SRS_RTMP_TYPE_AUDIO) {
2347 - srs_human_trace("Audio packet type=%s, dts=%d, pts=%d, diff=%d, size=%d, %s(%s,%s,%s,%s)",  
2348 - srs_human_flv_tag_type2string(type), timestamp, pts, diff, size, 2356 + srs_human_trace("Audio packet type=%s, dts=%d, pts=%d, diff=%d, ndiff=%d, size=%d, %s(%s,%s,%s,%s)",
  2357 + srs_human_flv_tag_type2string(type), timestamp, pts, diff, ndiff, size,
2349 srs_human_flv_audio_sound_format2string(srs_utils_flv_audio_sound_format(data, size)), 2358 srs_human_flv_audio_sound_format2string(srs_utils_flv_audio_sound_format(data, size)),
2350 srs_human_flv_audio_sound_rate2string(srs_utils_flv_audio_sound_rate(data, size)), 2359 srs_human_flv_audio_sound_rate2string(srs_utils_flv_audio_sound_rate(data, size)),
2351 srs_human_flv_audio_sound_size2string(srs_utils_flv_audio_sound_size(data, size)), 2360 srs_human_flv_audio_sound_size2string(srs_utils_flv_audio_sound_size(data, size)),
@@ -2353,8 +2362,8 @@ int srs_human_print_rtmp_packet2(char type, u_int32_t timestamp, char* data, int @@ -2353,8 +2362,8 @@ int srs_human_print_rtmp_packet2(char type, u_int32_t timestamp, char* data, int
2353 srs_human_flv_audio_aac_packet_type2string(srs_utils_flv_audio_aac_packet_type(data, size)) 2362 srs_human_flv_audio_aac_packet_type2string(srs_utils_flv_audio_aac_packet_type(data, size))
2354 ); 2363 );
2355 } else if (type == SRS_RTMP_TYPE_SCRIPT) { 2364 } else if (type == SRS_RTMP_TYPE_SCRIPT) {
2356 - srs_human_verbose("Data packet type=%s, time=%d, diff=%d, size=%d",  
2357 - srs_human_flv_tag_type2string(type), timestamp, diff, size); 2365 + srs_human_verbose("Data packet type=%s, time=%d, diff=%d, ndiff=%d, size=%d",
  2366 + srs_human_flv_tag_type2string(type), timestamp, diff, ndiff, size);
2358 int nparsed = 0; 2367 int nparsed = 0;
2359 while (nparsed < size) { 2368 while (nparsed < size) {
2360 int nb_parsed_this = 0; 2369 int nb_parsed_this = 0;
@@ -2370,8 +2379,8 @@ int srs_human_print_rtmp_packet2(char type, u_int32_t timestamp, char* data, int @@ -2370,8 +2379,8 @@ int srs_human_print_rtmp_packet2(char type, u_int32_t timestamp, char* data, int
2370 srs_freep(amf0_str); 2379 srs_freep(amf0_str);
2371 } 2380 }
2372 } else { 2381 } else {
2373 - srs_human_trace("Rtmp packet type=%#x, dts=%d, pts=%d, diff=%d, size=%d",  
2374 - type, timestamp, pts, diff, size); 2382 + srs_human_trace("Rtmp packet type=%#x, dts=%d, pts=%d, diff=%d, ndiff=%d, size=%d",
  2383 + type, timestamp, pts, diff, ndiff, size);
2375 } 2384 }
2376 2385
2377 return ret; 2386 return ret;
@@ -904,6 +904,7 @@ extern const char* srs_human_flv_audio_aac_packet_type2string(char aac_packet_ty @@ -904,6 +904,7 @@ extern const char* srs_human_flv_audio_aac_packet_type2string(char aac_packet_ty
904 */ 904 */
905 extern int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int size); 905 extern int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int size);
906 extern int srs_human_print_rtmp_packet2(char type, u_int32_t timestamp, char* data, int size, u_int32_t pre_timestamp); 906 extern int srs_human_print_rtmp_packet2(char type, u_int32_t timestamp, char* data, int size, u_int32_t pre_timestamp);
  907 +extern int srs_human_print_rtmp_packet3(char type, u_int32_t timestamp, char* data, int size, u_int32_t pre_timestamp, int64_t pre_now);
907 908
908 // log to console, for use srs-librtmp application. 909 // log to console, for use srs-librtmp application.
909 extern const char* srs_human_format_time(); 910 extern const char* srs_human_format_time();