From 6bb0ed36c0c4bfdde6ad76228a5dd42284ef72b1 Mon Sep 17 00:00:00 2001 From: Sebastian Reimers Date: Tue, 16 May 2023 15:45:46 +0200 Subject: [PATCH 1/2] jbuf: fix frame count Since packets can be lost or late/reorderd, this can lead to multiple counting. --- src/jbuf/jbuf.c | 17 ++++---- test/jbuf.c | 107 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 82 insertions(+), 42 deletions(-) diff --git a/src/jbuf/jbuf.c b/src/jbuf/jbuf.c index f205e48a4..fc06c0057 100644 --- a/src/jbuf/jbuf.c +++ b/src/jbuf/jbuf.c @@ -408,16 +408,19 @@ int jbuf_put(struct jbuf *jb, const struct rtp_header *hdr, void *mem) f->hdr = *hdr; f->mem = mem_ref(mem); - /* Count not equal timestamp frames (e.g. video) */ - if (f->le.prev) { - struct packet *pre_f = f->le.prev->data; + jb->nf = 1; + LIST_FOREACH(&jb->packetl, le) + { + struct packet *cur_p = le->data; + if (!le->next) + break; + + struct packet *next_p = le->next->data; - if (f->hdr.ts != pre_f->hdr.ts) + /* Count not equal timestamp frames (e.g. video) */ + if (cur_p->hdr.ts != next_p->hdr.ts) ++jb->nf; } - else { - ++jb->nf; - } out: mtx_unlock(jb->lock); diff --git a/test/jbuf.c b/test/jbuf.c index e4329e584..091435b4c 100644 --- a/test/jbuf.c +++ b/test/jbuf.c @@ -201,41 +201,41 @@ int test_jbuf_adaptive(void) /* Four frames */ DEBUG_INFO("test frame: Four frames\n"); jbuf_flush(jb); - hdr.seq = 320; - hdr.ts = 320; + hdr.seq = 1; + hdr.ts = 100; err = jbuf_put(jb, &hdr, frv[0]); TEST_ERR(err); - hdr.seq = 480; - hdr.ts = 480; + hdr.seq = 2; + hdr.ts = 200; err = jbuf_put(jb, &hdr, frv[1]); TEST_ERR(err); - hdr.seq = 490; - hdr.ts = 490; + hdr.seq = 3; + hdr.ts = 300; err = jbuf_put(jb, &hdr, frv[2]); TEST_ERR(err); - hdr.seq = 491; - hdr.ts = 491; + hdr.seq = 4; + hdr.ts = 400; err = jbuf_put(jb, &hdr, frv[3]); TEST_ERR(err); err = jbuf_get(jb, &hdr2, &mem); TEST_EQUALS(EAGAIN, err); - TEST_EQUALS(320, hdr2.seq); + TEST_EQUALS(1, hdr2.seq); TEST_EQUALS(mem, frv[0]); mem = mem_deref(mem); err = jbuf_get(jb, &hdr2, &mem); TEST_EQUALS(EAGAIN, err); - TEST_EQUALS(480, hdr2.seq); + TEST_EQUALS(2, hdr2.seq); TEST_EQUALS(mem, frv[1]); mem = mem_deref(mem); err = jbuf_get(jb, &hdr2, &mem); TEST_EQUALS(0, err); - TEST_EQUALS(490, hdr2.seq); + TEST_EQUALS(3, hdr2.seq); TEST_EQUALS(mem, frv[2]); mem = mem_deref(mem); @@ -258,7 +258,7 @@ int test_jbuf_adaptive_video(void) { struct rtp_header hdr, hdr2; struct jbuf *jb = NULL; - char *frv[4]; + char *frv[5]; uint32_t i; void *mem = NULL; int err; @@ -281,53 +281,90 @@ int test_jbuf_adaptive_video(void) } } - /* Four packets */ - DEBUG_INFO("test: 4 packets (3 frames)\n"); + + /* --- Test unordered insert --- */ jbuf_flush(jb); - hdr.seq = 320; - hdr.ts = 320; + + hdr.seq = 1; + hdr.ts = 100; err = jbuf_put(jb, &hdr, frv[0]); TEST_ERR(err); TEST_EQUALS(1, jbuf_frames(jb)); + TEST_EQUALS(1, jbuf_packets(jb)); - hdr.seq = 480; - hdr.ts = 320; /* Same frame */ + hdr.seq = 2; + hdr.ts = 100; /* Same frame */ err = jbuf_put(jb, &hdr, frv[1]); TEST_ERR(err); TEST_EQUALS(1, jbuf_frames(jb)); + TEST_EQUALS(2, jbuf_packets(jb)); - hdr.seq = 490; - hdr.ts = 490; + hdr.seq = 4; + hdr.ts = 200; err = jbuf_put(jb, &hdr, frv[2]); TEST_ERR(err); TEST_EQUALS(2, jbuf_frames(jb)); + TEST_EQUALS(3, jbuf_packets(jb)); - hdr.seq = 491; - hdr.ts = 491; + hdr.seq = 3; /* unordered late packet */ + hdr.ts = 200; err = jbuf_put(jb, &hdr, frv[3]); TEST_ERR(err); + TEST_EQUALS(2, jbuf_frames(jb)); + TEST_EQUALS(4, jbuf_packets(jb)); + + hdr.seq = 5; + hdr.ts = 300; + err = jbuf_put(jb, &hdr, frv[4]); + TEST_ERR(err); TEST_EQUALS(3, jbuf_frames(jb)); + TEST_EQUALS(5, jbuf_packets(jb)); - err = jbuf_get(jb, &hdr2, &mem); - TEST_EQUALS(EAGAIN, err); - TEST_EQUALS(320, hdr2.seq); - TEST_EQUALS(mem, frv[0]); - mem = mem_deref(mem); + + /* --- Test lost get --- */ + jbuf_flush(jb); + + hdr.seq = 1; + hdr.ts = 100; + err = jbuf_put(jb, &hdr, frv[0]); + TEST_ERR(err); + TEST_EQUALS(1, jbuf_frames(jb)); + TEST_EQUALS(1, jbuf_packets(jb)); + + hdr.seq = 2; + hdr.ts = 100; /* Same frame */ + err = jbuf_put(jb, &hdr, frv[1]); + TEST_ERR(err); + TEST_EQUALS(1, jbuf_frames(jb)); + TEST_EQUALS(2, jbuf_packets(jb)); + + /* LOST hdr.seq = 3; */ + + hdr.seq = 4; + hdr.ts = 200; + err = jbuf_put(jb, &hdr, frv[2]); + TEST_ERR(err); + TEST_EQUALS(2, jbuf_frames(jb)); + TEST_EQUALS(3, jbuf_packets(jb)); + + hdr.seq = 5; + hdr.ts = 300; + err = jbuf_put(jb, &hdr, frv[3]); + TEST_ERR(err); + TEST_EQUALS(3, jbuf_frames(jb)); + TEST_EQUALS(4, jbuf_packets(jb)); err = jbuf_get(jb, &hdr2, &mem); TEST_EQUALS(EAGAIN, err); - TEST_EQUALS(480, hdr2.seq); - TEST_EQUALS(mem, frv[1]); mem = mem_deref(mem); + TEST_EQUALS(3, jbuf_frames(jb)); + TEST_EQUALS(3, jbuf_packets(jb)); err = jbuf_get(jb, &hdr2, &mem); - TEST_EQUALS(0, err); - TEST_EQUALS(490, hdr2.seq); - TEST_EQUALS(mem, frv[2]); + TEST_EQUALS(EAGAIN, err); mem = mem_deref(mem); - - err = jbuf_get(jb, &hdr2, &mem); - TEST_EQUALS(ENOENT, err); + TEST_EQUALS(2, jbuf_frames(jb)); + TEST_EQUALS(2, jbuf_packets(jb)); err = 0; From 8686db67d6ea40445945e1861c6e56ca91fc23eb Mon Sep 17 00:00:00 2001 From: Sebastian Reimers Date: Wed, 17 May 2023 09:56:40 +0200 Subject: [PATCH 2/2] jbuf: fix rdiff packet/frame ratio calculation --- src/jbuf/jbuf.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/jbuf/jbuf.c b/src/jbuf/jbuf.c index fc06c0057..ac01c9535 100644 --- a/src/jbuf/jbuf.c +++ b/src/jbuf/jbuf.c @@ -254,6 +254,7 @@ static void calc_rdiff(struct jbuf *jb, uint16_t seq) int32_t adiff; int32_t s; /**< EMA coefficient */ uint32_t wish; + uint32_t max = jb->max; bool down = false; if (jb->jbtype != JBUF_ADAPTIVE) @@ -262,6 +263,12 @@ static void calc_rdiff(struct jbuf *jb, uint16_t seq) if (!jb->seq_get) return; + uint32_t fpr = jb->n / jb->nf; /* frame packet ratio */ + if (!fpr) + fpr = 1; + + max = max / fpr; + rdiff = (int16_t)(jb->seq_put + 1 - seq); adiff = abs(rdiff * JBUF_RDIFF_EMA_COEFF); s = adiff > jb->rdiff ? JBUF_RDIFF_UP_SPEED : @@ -269,12 +276,12 @@ static void calc_rdiff(struct jbuf *jb, uint16_t seq) jb->wish > 1 ? 2 : 3; jb->rdiff += (adiff - jb->rdiff) * s / JBUF_RDIFF_EMA_COEFF; - wish = (uint32_t) (jb->rdiff / JBUF_RDIFF_EMA_COEFF); + wish = (uint32_t) (jb->rdiff / JBUF_RDIFF_EMA_COEFF / fpr); if (wish < jb->min) wish = jb->min; - if (wish >= jb->max) - wish = jb->max - 1; + if (wish >= max) + wish = max - 1; if (wish > jb->wish) { DEBUG_INFO("wish size changed %u --> %u\n", jb->wish, wish);