Hey Kal, On Sun, Feb 26, 2017 at 8:14 AM, b17 c0de <b17c...@gmail.com> wrote: > Hi Asterisk Community, > Is it possible to have Asterisk trottle outgoing RTP packets when > received to-be-forwarded samples are from packets with a larger ptime? > I am using Asterisk as SIP proxy between two devices. When the sending > device uses a ptime larger than the receiving device, Asterisk > forwards the samples in bursts soon after a packet is received. > > For example, consider the following setup: > > [Device A] == ptime=300ms ==> [Asterisk] == ptime=20ms ==> [Device B] > > As soon as Asterisk receives a packet (300ms) from Device A it > transcodes 300ms worth of samples and sends 15 Packets (20 ms) to > Device B. This is a problem when Device B has a small buffer. My > testing shows that typical SIP phones cannot handle this case. > > What is the best solution to this problem? Is there a way to enable > clocked/throttled RTP packet transmission? If this is currently not > possible, can someone point me in the right direction as to where I > need to patch Asterisk to get this to work? I am willing to upstream > any changes I make to support this. > > I am currently using Asterisk 12.3.
I don't think that Asterisk currently has a way of spacing out the delivery times on the relayed packets in your example above. My guess is that you'll want to work on it in res/res_rtp_asterisk.c, starting in ast_rtp_write(). There is a smoother that is created dependent on the ptime (framing_ms): if (!rtp->smoother && ast_format_can_be_smoothed(format)) { unsigned int framing_ms = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(instance)); int is_slinear = ast_format_cache_is_slinear(format); if (!framing_ms && is_slinear) { framing_ms = ast_format_get_default_ms(format); } if (framing_ms) { rtp->smoother = ast_smoother_new((framing_ms * ast_format_get_minimum_bytes(format)) / ast_format_get_minimum_ms(format)); if (!rtp->smoother) { ast_log(LOG_WARNING, "Unable to create smoother: format %s ms: %u len: %u\n", ast_format_get_name(format), framing_ms, ast_format_get_minimum_bytes(format)); return -1; } if (is_slinear) { ast_smoother_set_flags(rtp->smoother, AST_SMOOTHER_FLAG_BE); } } } A smoother is basically a circular buffer that input data of any size is placed into (i.e. 300 ms packets), and repacketized output data (i.e. 20 ms packets) is pulled from. The end of ast_rtp_write() has a piece of code: /* Feed audio frames into the actual function that will create a frame and send it */ if (rtp->smoother) { struct ast_frame *f; if (ast_smoother_test_flag(rtp->smoother, AST_SMOOTHER_FLAG_BE)) { ast_smoother_feed_be(rtp->smoother, frame); } else { ast_smoother_feed(rtp->smoother, frame); } while ((f = ast_smoother_read(rtp->smoother)) && (f->data.ptr)) { ast_rtp_raw_write(instance, f, codec); } The culprit of your fast write timing is probably the ast_rtp_raw_write inside the while loop. You'll need to think about ways to asynchronously space out the transmission. You don't want to do it by blocking in that function IMHO, due to potentially blocking other things from happening in Asterisk that aren't expecting ast_rtp_write to block. Sounds like a fun problem, by the way :-) Best wishes, and good luck on it! If you have any more questions, feel free to ask them here, or frequently we inhabit the #asterisk-dev IRC channel on irc.freenode.net. -- Matthew Fredrickson Digium, Inc. | Engineering Manager 445 Jan Davis Drive NW - Huntsville, AL 35806 - USA -- _____________________________________________________________________ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- asterisk-dev mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-dev