Skip to content
Draft

Plc #91

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion debian/changelog
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
asterisk (8:18.10.0-1~wazo2) wazo-dev-buster; urgency=medium
asterisk (8:18.10.0-1~wazo5) wazo-dev-buster; urgency=medium

* Limit opus ptime

-- Wazo Maintainers <dev+pkg@wazo.community> Mon, 28 Feb 2022 11:40:37 -0500

asterisk (8:18.10.0-1~wazo4) wazo-dev-buster; urgency=medium

* Asterisk 18.10.0

Expand Down
13 changes: 13 additions & 0 deletions debian/patches/customize-opus
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Index: asterisk-18.10.0/include/asterisk/opus.h
===================================================================
--- asterisk-18.10.0.orig/include/asterisk/opus.h
+++ asterisk-18.10.0/include/asterisk/opus.h
@@ -53,7 +53,7 @@
/*! \brief Default attribute values */
#define CODEC_OPUS_DEFAULT_SAMPLE_RATE 48000
#define CODEC_OPUS_DEFAULT_MAX_PLAYBACK_RATE 48000
-#define CODEC_OPUS_DEFAULT_MAX_PTIME 120
+#define CODEC_OPUS_DEFAULT_MAX_PTIME 20
#define CODEC_OPUS_DEFAULT_PTIME 20
#define CODEC_OPUS_DEFAULT_BITRATE -1000 /* OPUS_AUTO */
#define CODEC_OPUS_DEFAULT_CBR 0
175 changes: 175 additions & 0 deletions debian/patches/enable_native_plc.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
Index: asterisk-18.10.0/main/translate.c
===================================================================
--- asterisk-18.10.0.orig/main/translate.c
+++ asterisk-18.10.0/main/translate.c
@@ -356,6 +356,7 @@ static struct ast_trans_pvt *newpvt(stru
pvt->f.offset = AST_FRIENDLY_OFFSET;
pvt->f.src = pvt->t->name;
pvt->f.data.ptr = pvt->outbuf.c;
+ pvt->f.seqno = 0x10000;

/*
* If the translator has not provided a format
@@ -564,14 +565,17 @@ static struct ast_frame *generate_interp
/*! \brief do the actual translation */
struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
{
+ const unsigned int rtp_seqno_max_value = 0xffff;
struct ast_trans_pvt *p = path;
- struct ast_frame *out;
+ struct ast_frame *out_last, *out = NULL;
struct timeval delivery;
int has_timing_info;
long ts;
long len;
- int seqno;
+ int seqno, frames_missing;

+ /* RTCP frames can be received with different seqno from main/channel.c:.__ast_queue_frame */
+ /* These frames are forwarded to the translator for feedback before doing PLC */
if (f->frametype == AST_FRAME_RTCP) {
/* Just pass the feedback to the right callback, if it exists.
* This "translation" does nothing so return a null frame. */
@@ -583,6 +587,38 @@ struct ast_frame *ast_translate(struct a
return &ast_null_frame;
}

+ /* Determine the amount of lost packets for PLC */
+ /* But not at start with first frame = path->f.seqno is still 0x10000 */
+ /* But not when there is no sequence number = frame created internally */
+ if ((path->f.seqno <= rtp_seqno_max_value) && (path->f.seqno != f->seqno)) {
+ if (f->seqno < path->f.seqno) { /* seqno overrun situation */
+ frames_missing = rtp_seqno_max_value + f->seqno - path->f.seqno - 1;
+ } else {
+ frames_missing = f->seqno - path->f.seqno - 1;
+ }
+ /* Out-of-order packet - more precise: late packet */
+ if ((rtp_seqno_max_value + 1) / 2 < frames_missing) {
+ if (consume) {
+ ast_frfree(f);
+ }
+ /*
+ * Do not pass late packets to any transcoding module, because that
+ * confuses the state of any library (packets inter-depend). With
+ * the next packet, this one is going to be treated as lost packet.
+ */
+ return NULL;
+ }
+
+ if (frames_missing > 96) {
+ struct ast_str *str = ast_str_alloca(256);
+
+ /* not DEBUG but NOTICE because of WARNING in main/cannel.c:__ast_queue_frame */
+ ast_log(LOG_NOTICE, "%d lost frame(s) %d/%d %s\n", frames_missing, f->seqno, path->f.seqno, ast_translate_path_to_str(path, &str));
+ }
+ } else {
+ frames_missing = 0;
+ }
+
has_timing_info = ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO);
ts = f->ts;
len = f->len;
@@ -611,19 +647,94 @@ struct ast_frame *ast_translate(struct a
f->samples, ast_format_get_sample_rate(f->subclass.format)));
}
delivery = f->delivery;
- for (out = f; out && p ; p = p->next) {
- struct ast_frame *current = out;

- do {
- framein(p, current);
- current = AST_LIST_NEXT(current, frame_list);
- } while (current);
- if (out != f) {
- ast_frfree(out);
+ for (out_last = NULL; frames_missing + 1; frames_missing--) {
+ struct ast_frame *frame_to_translate, *inner_head;
+ struct ast_frame missed = {
+ .frametype = AST_FRAME_VOICE,
+ .subclass.format = f->subclass.format,
+ .datalen = 0,
+ /* In RTP, the amount of samples might change anytime */
+ /* If that happened while frames got lost, what to do? */
+ .samples = f->samples, /* FIXME */
+ .src = __FUNCTION__,
+ .data.uint32 = 0,
+ .delivery.tv_sec = 0,
+ .delivery.tv_usec = 0,
+ .flags = 0,
+ /* RTP sequence number is between 0x0001 and 0xffff */
+ .seqno = (rtp_seqno_max_value + 1 + f->seqno - frames_missing) & rtp_seqno_max_value,
+ };
+
+ if (frames_missing) {
+ frame_to_translate = &missed;
+ } else {
+ frame_to_translate = f;
+ }
+
+ /* The translation path from one format to another might contain several steps */
+ /* out* collects the result for missed frame(s) and input frame(s) */
+ /* out is the result of the conversion of all frames, translated into the destination format */
+ /* out_last is the last frame in that list, to add frames faster */
+ for (p = path, inner_head = frame_to_translate; inner_head && p; p = p->next) {
+ struct ast_frame *current, *inner_last, *inner_prev = frame_to_translate;
+
+ /* inner* collects the result of each conversion step, the input for the next step */
+ /* inner_head is a list of frames created by each conversion step */
+ /* inner_last is the last frame in that list, to add frames faster */
+ for (inner_last = NULL, current = inner_head; current; current = AST_LIST_NEXT(current, frame_list)) {
+ struct ast_frame *tmp;
+
+ framein(p, current);
+ tmp = p->t->frameout(p);
+
+ if (!tmp) {
+ continue;
+ } else if (inner_last) {
+ struct ast_frame *t;
+
+ /* Determine the last frame of the list before appending to it */
+ while ((t = AST_LIST_NEXT(inner_last, frame_list))) {
+ inner_last = t;
+ }
+ AST_LIST_NEXT(inner_last, frame_list) = tmp;
+ } else {
+ inner_prev = inner_head;
+ inner_head = tmp;
+ inner_last = tmp;
+ }
+ }
+
+ /* The current step did not create any frames = no frames for the next step */
+ /* The steps are not lost because framein buffered those for the next input frame */
+ if (!inner_last) {
+ inner_prev = inner_head;
+ inner_head = NULL;
+ }
+ if (inner_prev != frame_to_translate) {
+ ast_frfree(inner_prev); /* Frees just the intermediate lists */
+ }
+ }
+
+ /* This frame created no frames after translation = continue with next frame */
+ /* The frame is not lost because framein buffered it to be combined with the next frame */
+ if (!inner_head) {
+ continue;
+ } else if (out_last) {
+ struct ast_frame *t;
+
+ /* Determine the last frame of the list before appending to it */
+ while ((t = AST_LIST_NEXT(out_last, frame_list))) {
+ out_last = t;
+ }
+ AST_LIST_NEXT(out_last, frame_list) = inner_head;
+ } else {
+ out = inner_head;
+ out_last = inner_head;
}
- out = p->t->frameout(p);
}

+
if (!out) {
out = generate_interpolated_slin(path, f);
}
2 changes: 2 additions & 0 deletions debian/patches/series
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ wazo_bridge_variables
wazo_mixmonitor_events
wazo_stun_recurring_resolution
increase-max-sdp-media
enable_native_plc.patch
customize-opus