<div dir="ltr"><div><div><div>Hi Matt,<br><br>Thanks for this nice explanation.<br><br></div>Well,  we still don't know if we are going to do it or not, it is still a pending decision.<br><br></div>But i do have some comments ref your response, responding inline.<br><br></div>General comment: By adding the support for NACK, i meant just adding the ability<br>to forward the RTCP FB messages, i do agree that adding the capability in asterisk<br>to generate NACKs on its own will make it much more complicated?<br><div><div><div><br>(1) You'll need to modify rtp_engine and res_rtp_asterisk to<br>
understand compound RTCP packets properly. Currently, we always assume<br>
that the RTCP packets contain a single SR/RR: that means modifications<br>
to the parsing in ast_rtcp_read, as well as the conversion of received<br>
RTCP reports in rtp_engine into JSON for delivery to RTP Stasis topic<br>
consumers. Note that this would be an opportune time to make the<br>
parsing in ast_rtcp_read not be quite so terrible as it is today.<br>
<br>
(2) Going along with #1, you'll need to add additional RTCP report<br>
types - both when reading and when writing. Currently, Asterisk only<br>
supports SR/RR. The RFC mandates FR reports, along with SDES packets.<br>
You'll also need to change the algorithm for when reports are<br>
scheduled. Since RFC 4585 modifies the scheduling algorithm, you'll<br>
pretty much have to abandon how scheduling is set up currently in<br>
ast_rtp_read. There are different modes of operation, each with slight<br>
variations to the algorithm for how/when reports should be sent. A<br>
state machine would probably be handy for this.<br><br></div><div>Nitesh -- since asterisk is just going to forward the RTCP FB reports, won't it <br>be sufficient to parse the RTCP FB messages, adapt the packet header like SSRC<br></div><div>and other stuff and just forward it, without modifying the current algorithm?<br></div><div>
<br>
(3) NACK mode. I would be very careful here: as a B2BUA, Asterisk<br>
*always* assumes there are only two participants in an RTP session -<br>
and making Asterisk realize that this isn't the case is going to be<br>
more challenging than you may think. Asterisk has a lot of<br>
implementation 'shortcuts' it takes in RTCP statistic management that<br>
it takes because it knows that there is only one other RTP participant<br>
other than itself: if you go down the road of wanting to maintain<br>
additional statistics beyond the RTP instance and whoever it is<br>
talking to, the scope of this would expand dramatically.<br>
</div><div>Nitesh -- I am not sure if i understood your comment, why does it need to maintain <br></div><div>addiitonal info beyond RTP instance, in my opinion, for forwarding RTCP FB reports,<br></div><div>all we need is the SSRC and sequence numbers? <br></div><div><br>
(4) If I'm reading the RFC correctly, you _may_ not need to buffer the<br>
RTP packets themselves; rather, you need to inform the other side of<br>
the RTP packets you've lost. Generally, this means keeping a limited<br>
history of which RTP sequence numbers you've received, and which ones<br>
are missed. When constructing the NACK message (in 5a), you'd see if<br>
you had a missed RTP sequence number, then look to see if any of the<br>
16 RTP packets after that one were also missed. After reporting this,<br>
the buffer could be flushed - how long the buffer is probably depends<br>
on the frequency of report sending, which is variable as per (2).<br>
<br></div><div>Nitesh -- I have made this assumption considering that many traditional<br></div><div>SIP phones don't support NACK and even if they do, they don't send the<br></div><div>retransmission as specified in the RFC 4588. <br></div><div>This draft <a href="http://tools.ietf.org/pdf/draft-ietf-straw-b2bua-rtcp-02.pdf">http://tools.ietf.org/pdf/draft-ietf-straw-b2bua-rtcp-02.pdf</a> talks <br>about the issue of handling the NACK messages in B2BUA environment.<br></div><div>Here is a piece of text from Section 4 of this draft:<br><span style="background-color:rgb(255,255,255)"><br></span><div dir="ltr" style="font-size:17.16px;font-family:monospace">   <span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">It is worth noting that some additional care may be needed, with</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   respect to RTCP, when acting as an intermediary between two secure</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   sessions.  Specifically, issues may arise when relaying <span class="">NACK</span> feedback</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   originated by a user who failed to receive some RTP packets, that</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   were instead received by the B2BUA: such an issue might occur when</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   the packet loss happens between the user and the B2BUA itself, and</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   not between the RTP packet sender and the B2BUA.  Such a situation</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   might result in the RTP media sender retransmitting the encrypted</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   packet, which would then be rejected by the B2BUA as a replayed one.</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   However, this issue is well known and addressed in [</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">RFC4588</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">], which</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   both the B2BUA and the involved participants in the communication</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   SHOULD make use of to prevent it from happening.  This mechanism</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   allows for a Redundancy RTP Stream to be used for the purpose, which</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   would prevent the replay error.  Of course, all recommendations given</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   previously with respect to<span style></span> managing SSRCs across the B2BUA still</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   apply here as well: in fact, such a redundant RTP stream would make</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   use of a different SSRC, that would need to be taken care of both at</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   the RTP and the SDP level.  If [</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">RFC4588</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">] is not supported, the B2BUA</span></i></font></span></div><div dir="ltr" style="font-family:monospace"><span style="background-color:rgb(255,255,255)"><font size="4"><i><span style="color:rgb(102,102,102)">   SHOULD handle NACK packets directly, and only forward feedback on</span></i></font></span></div><font size="4"><i><span style="color:rgb(102,102,102)"><span style="background-color:rgb(0,0,0)"><span style="background-color:rgb(255,255,255)">   lost packets it has not access to</span><br></span></span></i></font></div><div><font size="4"><i><span style="color:rgb(102,102,102)"><span style="background-color:rgb(0,0,0)"><br>
</span></span></i></font><br>
<br>
(5) RTCP feedback messages. The transport layer feedback messages<br>
would obviously be provided by the RTP engine and/or res_rtp_asterisk.<br>
However, the other layers - payload/application - should have<br>
corresponding APIs in rtp_engine. In particular, the codec layer<br>
(payload) would be interesting, as it would require the ability for<br>
codec modules (or something else in the media 'section' of Asterisk)<br>
to take an RTP instance and register a handler for providing feedback<br>
messages at opportune times. The application layer would be similar,<br>
except that currently, we probably wouldn't have an implementation.<br>
You may want to consider that as 'future work', as it is probably<br>
sufficient to be a project in its own right.<br><br>Nitesh -- Do we require to register any handlers if we just care about forwarding <br>the RTCP FB messages?<br><br>
  (a) Generic NACK: these messages should be implemented in such a<br>
fashion that res_rtp_asterisk can have one be constructed based on the<br>
statistics in (4). A part of me wishes all of this were implemented in<br>
RTP engine, so that other RTP implementations could take advantage of<br>
the RTCP work. That's a consideration that should be given some<br>
thought, given how much of the RTCP implementation would have to be<br>
ripped apart by this work anyway.<br>
  (b) PLI/SLI/RPSI: I'm not sure these apply to Asterisk very well. We<br>
don't decode video, so it's kind of immaterial. You may want to have<br>
the ability for Asterisk to pass through these types of RTCP messages<br>
from a video decoder to a video encoder; that would entail<br>
understanding the RTCP messages, enqueuing a control frame onto the<br>
channel, and - in the far end - taking that control frame and turning<br>
it into the appropriate information on the other side of the bridge.<br>
There's bridging considerations to think through here on how the<br>
control frame is propagated, particularly for multi-party bridges.<br>
<br>
If you're still interested in doing this work, please do let me us<br>
know! I think the first major hurdle here is to hammer out how all of<br>
this can be effectively introduced into the RTP engine/implementation<br>
in Asterisk - as a large part of what makes this so difficult is the<br>
non-extensible nature of Asterisk's RTP implementation. It may be that<br>
we can help out some with that part, such that the actual act of<br>
implementing the RFC and its various feedback mechanisms is a bit<br>
easier.<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Dec 19, 2014 at 4:36 PM, Matthew Jordan <span dir="ltr"><<a href="mailto:mjordan@digium.com" target="_blank">mjordan@digium.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">On Thu, Dec 18, 2014 at 5:06 AM, Nitesh Bansal <<a href="mailto:nitesh.bansal@gmail.com">nitesh.bansal@gmail.com</a>> wrote:<br>
><br>
> Hello,<br>
><br>
> I am talking about NACK in the context of RTCP feedback (a=rtcp-fb:* nack) to request retransmission of lost frames.<br>
> I would like to advertise in my SDP that asterisk supports NACK, so WebRTC browsers can<br>
> request for lost packets, lost FIR or PLI messages via RTCP feedback.<br>
><br>
> Since asterisk isn't source of the video, it will have to buffer the RTP messages received from the remote peer and retransmit<br>
> them when requested by WebRTC browsers.<br>
<br>
<br>
</span>Short answer: complicated and hard. :-)<br>
<br>
For the sake of the explanation, I'm going to assume you want to<br>
implement RFC 4585 (<a href="https://tools.ietf.org/html/rfc4585" target="_blank">https://tools.ietf.org/html/rfc4585</a>)<br>
<br>
Part of this will be because you will be fighting inside<br>
res_rtp_asterisk - which is a module that is long overdue for a<br>
serious overhaul. Much like chan_sip, it has grown organically over<br>
the years, and suffers from a lack of structure in certain parts (and<br>
some dead code, and strange hacks for equipment that probably not<br>
longer exists, etc.) Unlike chan_sip, it's not nearly so large that<br>
it's impossible to work inside of - but it is challenging.<br>
<br>
That isn't a reason _not_ to do this work, but it should be a<br>
consideration - you'll want to think through how you can modify<br>
res_rtp_asterisk such that the feedback mechanisms don't interfere<br>
with the 'normal' operation of res_rtp_asterisk. A decent portion of<br>
the work may just be simply restructuring res_rtp_asterisk to easily<br>
handle the addition.<br>
<br>
As for the work itself:<br>
<br>
(1) You'll need to modify rtp_engine and res_rtp_asterisk to<br>
understand compound RTCP packets properly. Currently, we always assume<br>
that the RTCP packets contain a single SR/RR: that means modifications<br>
to the parsing in ast_rtcp_read, as well as the conversion of received<br>
RTCP reports in rtp_engine into JSON for delivery to RTP Stasis topic<br>
consumers. Note that this would be an opportune time to make the<br>
parsing in ast_rtcp_read not be quite so terrible as it is today.<br>
<br>
(2) Going along with #1, you'll need to add additional RTCP report<br>
types - both when reading and when writing. Currently, Asterisk only<br>
supports SR/RR. The RFC mandates FR reports, along with SDES packets.<br>
You'll also need to change the algorithm for when reports are<br>
scheduled. Since RFC 4585 modifies the scheduling algorithm, you'll<br>
pretty much have to abandon how scheduling is set up currently in<br>
ast_rtp_read. There are different modes of operation, each with slight<br>
variations to the algorithm for how/when reports should be sent. A<br>
state machine would probably be handy for this.<br>
<br>
(3) NACK mode. I would be very careful here: as a B2BUA, Asterisk<br>
*always* assumes there are only two participants in an RTP session -<br>
and making Asterisk realize that this isn't the case is going to be<br>
more challenging than you may think. Asterisk has a lot of<br>
implementation 'shortcuts' it takes in RTCP statistic management that<br>
it takes because it knows that there is only one other RTP participant<br>
other than itself: if you go down the road of wanting to maintain<br>
additional statistics beyond the RTP instance and whoever it is<br>
talking to, the scope of this would expand dramatically.<br>
<br>
(4) If I'm reading the RFC correctly, you _may_ not need to buffer the<br>
RTP packets themselves; rather, you need to inform the other side of<br>
the RTP packets you've lost. Generally, this means keeping a limited<br>
history of which RTP sequence numbers you've received, and which ones<br>
are missed. When constructing the NACK message (in 5a), you'd see if<br>
you had a missed RTP sequence number, then look to see if any of the<br>
16 RTP packets after that one were also missed. After reporting this,<br>
the buffer could be flushed - how long the buffer is probably depends<br>
on the frequency of report sending, which is variable as per (2).<br>
<br>
(5) RTCP feedback messages. The transport layer feedback messages<br>
would obviously be provided by the RTP engine and/or res_rtp_asterisk.<br>
However, the other layers - payload/application - should have<br>
corresponding APIs in rtp_engine. In particular, the codec layer<br>
(payload) would be interesting, as it would require the ability for<br>
codec modules (or something else in the media 'section' of Asterisk)<br>
to take an RTP instance and register a handler for providing feedback<br>
messages at opportune times. The application layer would be similar,<br>
except that currently, we probably wouldn't have an implementation.<br>
You may want to consider that as 'future work', as it is probably<br>
sufficient to be a project in its own right.<br>
  (a) Generic NACK: these messages should be implemented in such a<br>
fashion that res_rtp_asterisk can have one be constructed based on the<br>
statistics in (4). A part of me wishes all of this were implemented in<br>
RTP engine, so that other RTP implementations could take advantage of<br>
the RTCP work. That's a consideration that should be given some<br>
thought, given how much of the RTCP implementation would have to be<br>
ripped apart by this work anyway.<br>
  (b) PLI/SLI/RPSI: I'm not sure these apply to Asterisk very well. We<br>
don't decode video, so it's kind of immaterial. You may want to have<br>
the ability for Asterisk to pass through these types of RTCP messages<br>
from a video decoder to a video encoder; that would entail<br>
understanding the RTCP messages, enqueuing a control frame onto the<br>
channel, and - in the far end - taking that control frame and turning<br>
it into the appropriate information on the other side of the bridge.<br>
There's bridging considerations to think through here on how the<br>
control frame is propagated, particularly for multi-party bridges.<br>
<br>
If you're still interested in doing this work, please do let me us<br>
know! I think the first major hurdle here is to hammer out how all of<br>
this can be effectively introduced into the RTP engine/implementation<br>
in Asterisk - as a large part of what makes this so difficult is the<br>
non-extensible nature of Asterisk's RTP implementation. It may be that<br>
we can help out some with that part, such that the actual act of<br>
implementing the RFC and its various feedback mechanisms is a bit<br>
easier.<br>
<br>
(Also: have you given any thought on how you'd test this in an<br>
automated fashion? :-)<br>
<br>
Matt<br>
<span class=""><font color="#888888"><br>
--<br>
Matthew Jordan<br>
Digium, Inc. | Engineering Manager<br>
445 Jan Davis Drive NW - Huntsville, AL 35806 - USA<br>
Check us out at: <a href="http://digium.com" target="_blank">http://digium.com</a> & <a href="http://asterisk.org" target="_blank">http://asterisk.org</a><br>
</font></span><div class=""><div class="h5"><br>
--<br>
_____________________________________________________________________<br>
-- Bandwidth and Colocation Provided by <a href="http://www.api-digital.com" target="_blank">http://www.api-digital.com</a> --<br>
<br>
asterisk-dev mailing list<br>
To UNSUBSCRIBE or update options visit:<br>
   <a href="http://lists.digium.com/mailman/listinfo/asterisk-dev" target="_blank">http://lists.digium.com/mailman/listinfo/asterisk-dev</a><br>
</div></div></blockquote></div><br></div></div></div>