[FFmpeg-devel] [PATCH] libavformat/libsrt.c Add statistics option to output SRT statistics with av_log()
Ryan McCartney
ryan at mccartney.info
Tue Mar 19 13:34:36 EET 2024
---
libavformat/libsrt.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/libavformat/libsrt.c b/libavformat/libsrt.c
index a7aafea536..80d52b1737 100644
--- a/libavformat/libsrt.c
+++ b/libavformat/libsrt.c
@@ -56,6 +56,8 @@ typedef struct SRTContext {
int eid;
int64_t rw_timeout;
int64_t listen_timeout;
+ int64_t lastStatsTime;
+ int64_t stats;
int recv_buffer_size;
int send_buffer_size;
@@ -100,6 +102,7 @@ typedef struct SRTContext {
static const AVOption libsrt_options[] = {
{ "timeout", "Timeout of socket I/O operations (in microseconds)", OFFSET(rw_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
{ "listen_timeout", "Connection awaiting timeout (in microseconds)" , OFFSET(listen_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "stats", "Show SRT statistics in the log output", OFFSET(stats), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
{ "send_buffer_size", "Socket send buffer size (in bytes)", OFFSET(send_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
{ "recv_buffer_size", "Socket receive buffer size (in bytes)", OFFSET(recv_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
{ "pkt_size", "Maximum SRT packet size", OFFSET(payload_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, SRT_LIVE_MAX_PAYLOAD_SIZE, .flags = D|E, .unit = "payload_size" },
@@ -158,6 +161,29 @@ static int libsrt_neterrno(URLContext *h)
return os_errno ? AVERROR(os_errno) : AVERROR_UNKNOWN;
}
+static int libsrt_stats(URLContext *h,int read)
+{
+ SRTContext *s = h->priv_data;
+ SRT_TRACEBSTATS trace;
+
+ int ret = srt_bistats(s->fd, &trace, 0,1);
+ int64_t timeNow = trace.msTimeStamp;
+ int64_t timeNext = s->lastStatsTime + s->stats;
+
+ if((ret >= 0) && (timeNow > timeNext )){
+ s->lastStatsTime = timeNow;
+
+ if(read > 0){
+ av_log(h, AV_LOG_INFO, "[srt-stats] rate=%.2fMbps bw=%.2fMbps rtt=%.2fms total=%jdpkts retrans=%jdpkts loss=%jdpkts \n", trace.mbpsRecvRate,trace.mbpsBandwidth,trace.msRTT,trace.pktRecvTotal,trace.pktRcvRetrans,trace.pktRcvLossTotal);
+ }
+ else{
+ av_log(h, AV_LOG_INFO, "[srt-stats] rate=%.2fMbps bw=%.2fMbps rtt=%.2fms total=%jdpkts retrans=%jdpkts loss=%jdpkts \n", trace.mbpsSendRate,trace.mbpsBandwidth,trace.msRTT,trace.pktSentTotal,trace.pktRetrans,trace.pktSndLossTotal);
+ }
+ }
+
+ return 0;
+}
+
static int libsrt_getsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char * optnamestr, void * optval, int * optlen)
{
if (srt_getsockopt(fd, 0, optname, optval, optlen) < 0) {
@@ -557,6 +583,9 @@ static int libsrt_open(URLContext *h, const char *uri, int flags)
goto err;
}
}
+ if (av_find_info_tag(buf, sizeof(buf), "stats", p)) {
+ s->stats = strtol(buf, NULL, 10);
+ }
#if SRT_VERSION_VALUE >= 0x010302
if (av_find_info_tag(buf, sizeof(buf), "enforced_encryption", p)) {
s->enforced_encryption = strtol(buf, NULL, 10);
@@ -686,6 +715,10 @@ static int libsrt_read(URLContext *h, uint8_t *buf, int size)
SRTContext *s = h->priv_data;
int ret;
+ if(s->stats > 0){
+ libsrt_stats(h,1);
+ }
+
if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
ret = libsrt_network_wait_fd_timeout(h, s->eid, 0, h->rw_timeout, &h->interrupt_callback);
if (ret)
@@ -705,6 +738,10 @@ static int libsrt_write(URLContext *h, const uint8_t *buf, int size)
SRTContext *s = h->priv_data;
int ret;
+ if(s->stats > 0){
+ libsrt_stats(h,0);
+ }
+
if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
ret = libsrt_network_wait_fd_timeout(h, s->eid, 1, h->rw_timeout, &h->interrupt_callback);
if (ret)
--
2.43.0
More information about the ffmpeg-devel
mailing list