diff --git a/src/jbuf/jbuf.c b/src/jbuf/jbuf.c index 6d67a2c64..aba8c9951 100644 --- a/src/jbuf/jbuf.c +++ b/src/jbuf/jbuf.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -88,9 +89,64 @@ struct jbuf { #if JBUF_STAT struct jbuf_stat stat; /**< Jitter buffer Statistics */ #endif +#ifdef RE_JBUF_TRACE + uint64_t tr00; /**< Arrival of first packet */ + char buf[136]; /**< Buffer for trace */ +#endif }; +#ifdef RE_JBUF_TRACE +static void plot_jbuf(struct jbuf *jb, uint64_t tr) +{ + uint32_t treal; + uint32_t rdiff = (uint32_t)(jb->rdiff / (float)JBUF_RDIFF_EMA_COEFF); + + if (!jb->tr00) + jb->tr00 = tr; + + treal = (uint32_t) (tr - jb->tr00); + re_snprintf(jb->buf, sizeof(jb->buf), + "%s, 0x%p, %u, %u, %u, %u, %u", + __func__, /* row 1 - grep */ + jb, /* row 2 - grep optional */ + treal, /* row 3 - plot x-axis */ + rdiff, /* row 4 - plot */ + jb->wish, /* row 5 - plot */ + jb->n, /* row 6 - plot */ + jb->nf); /* row 7 - plot */ + re_trace_event("jbuf", "plot", 'P', NULL, 0, RE_TRACE_ARG_STRING_COPY, + "line", jb->buf); +} + + +static void plot_jbuf_event(struct jbuf *jb, char ph) +{ + uint32_t treal; + uint64_t tr; + + tr = tmr_jiffies(); + if (!jb->tr00) + jb->tr00 = tr; + + treal = (uint32_t) (tr - jb->tr00); + re_snprintf(jb->buf, sizeof(jb->buf), "%s, 0x%p, %u, %i", + __func__, /* row 1 - grep */ + jb, /* row 2 - grep optional */ + treal, /* row 3 - plot x-axis */ + 1); /* row 4 - plot */ + re_trace_event("jbuf", "plot", ph, NULL, 0, RE_TRACE_ARG_STRING_COPY, + "line", jb->buf); +} +#else +static void plot_jbuf_event(struct jbuf *jb, char ph) +{ + (void)jb; + (void)ph; +} +#endif + + /** Is x less than y? */ static inline bool seq_less(uint16_t x, uint16_t y) { @@ -155,6 +211,10 @@ static void jbuf_destructor(void *data) /* Free all packets in the pool list */ list_flush(&jb->pooll); mem_deref(jb->lock); + +#ifdef RE_JBUF_TRACE + (void)re_trace_close(); +#endif } @@ -216,6 +276,10 @@ int jbuf_alloc(struct jbuf **jbp, uint32_t min, uint32_t max) DEBUG_INFO("alloc: adding to pool list %u\n", i); } +#ifdef RE_JBUF_TRACE + (void)re_trace_init("re_jbuf.json"); +#endif + out: if (err) mem_deref(jb); @@ -379,6 +443,7 @@ int jbuf_put(struct jbuf *jb, const struct rtp_header *hdr, void *mem) /* Packet arrived too late to be put into buffer */ if (jb->seq_get && seq_less(seq, jb->seq_get + 1)) { STAT_INC(n_late); + plot_jbuf_event(jb, 'L'); DEBUG_INFO("packet too late: seq=%u " "(seq_put=%u seq_get=%u)\n", seq, jb->seq_put, jb->seq_get); @@ -417,6 +482,7 @@ int jbuf_put(struct jbuf *jb, const struct rtp_header *hdr, void *mem) /* Detect duplicates */ DEBUG_INFO("duplicate: seq=%u\n", seq); STAT_INC(n_dups); + plot_jbuf_event(jb, 'D'); list_insert_after(&jb->packetl, le, &f->le, f); packet_deref(jb, f); err = EALREADY; @@ -434,6 +500,7 @@ int jbuf_put(struct jbuf *jb, const struct rtp_header *hdr, void *mem) } STAT_INC(n_oos); + plot_jbuf_event(jb, 'S'); success: /* Update last sequence */ @@ -455,10 +522,14 @@ int jbuf_put(struct jbuf *jb, const struct rtp_header *hdr, void *mem) equal = (fc->hdr.ts == f->hdr.ts); } - if (!equal) + if (!equal) { ++jb->nf; + } out: +#ifdef RE_JBUF_TRACE + plot_jbuf(jb, tr); +#endif mtx_unlock(jb->lock); return err; } @@ -489,6 +560,7 @@ int jbuf_get(struct jbuf *jb, struct rtp_header *hdr, void **mem) DEBUG_INFO("not enough buffer packets - wait.. " "(n=%u wish=%u)\n", jb->n, jb->wish); STAT_INC(n_underflow); + plot_jbuf_event(jb, 'U'); err = ENOENT; goto out; } @@ -644,6 +716,7 @@ void jbuf_flush(struct jbuf *jb) n_flush = STAT_INC(n_flush); memset(&jb->stat, 0, sizeof(jb->stat)); jb->stat.n_flush = n_flush; + plot_jbuf_event(jb, 'F'); #endif mtx_unlock(jb->lock); }