diff --git a/debian/changelog b/debian/changelog index 4066f1eb..65500f1b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -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 Mon, 28 Feb 2022 11:40:37 -0500 + +asterisk (8:18.10.0-1~wazo4) wazo-dev-buster; urgency=medium * Asterisk 18.10.0 diff --git a/debian/patches/customize-opus b/debian/patches/customize-opus new file mode 100644 index 00000000..c66b0bb3 --- /dev/null +++ b/debian/patches/customize-opus @@ -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 diff --git a/debian/patches/enable_native_plc.patch b/debian/patches/enable_native_plc.patch new file mode 100644 index 00000000..6fb21fe1 --- /dev/null +++ b/debian/patches/enable_native_plc.patch @@ -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); + } diff --git a/debian/patches/series b/debian/patches/series index 61a8200e..860868e6 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -24,3 +24,5 @@ wazo_bridge_variables wazo_mixmonitor_events wazo_stun_recurring_resolution increase-max-sdp-media +enable_native_plc.patch +customize-opus