Different codecs for different VSP
-
- Posts: 179
- Joined: Thu Aug 27, 2009 3:00 am
Different codecs for different VSP
I am trying to figure out if it is possible in SS to use different codecs for different VSPs. My scenario is: I would like to use G726 for the calls between SS accounts without VSP, while use G711u for voip.ms to call PSTN (voip.ms does not support G726). Right now, if I set my ATA's preferred codec as G726 on both ends, there is no problem for calls between SS accounts, but there is sound quality problem when I call PSTN using voip.ms. I am wondering if it is possible to specify the codec in the Dial() method or other methods in the dialplan. Thanks.
Re: Different codecs for different VSP
It's sort of possible as the SDP from your ATA is exposed in the dialplan. However you'd really need to be a bit of a regular expression whiz to fiddle with it.
I'll be doing a little bit of work in that area over the coming week or two so I'll see what can be done about adding a more user friendly dialplan function to manipulate codecs.
I'll be doing a little bit of work in that area over the coming week or two so I'll see what can be done about adding a more user friendly dialplan function to manipulate codecs.
-
- Posts: 179
- Joined: Thu Aug 27, 2009 3:00 am
Re: Different codecs for different VSP
Aaron: Thanks for the reply. It will be very helpful to choose codecs in the dialplan. Do you have any quick sample dialplan for this purpose, or tell me which function could accept the codec as arguments in the Ruby dialplan script?
Best Regards,
David
Best Regards,
David
Re: Different codecs for different VSP
The ability to manipulate codecs on sipsorcery's side (to change the order of codecs, re-encode) would be very useful to me. My device automatically uses one of the higher bandwidth codecs. Changing the codec preferences on my device doesn't work (its buggy), but if I could either remove or reorder the codecs sent to the device, this could fix the issue for me.
Re: Different codecs for different VSP
I don't have any smaples but the dialplan method you can use to set a custom SDP packet is:davidnewton wrote:Aaron: Thanks for the reply. It will be very helpful to choose codecs in the dialplan. Do you have any quick sample dialplan for this purpose, or tell me which function could accept the codec as arguments in the Ruby dialplan script?
Best Regards,
David
Code: Select all
sys.SetCustomContent(string sdp)
Code: Select all
customSDP = req.Body
#Do some fancy manipulations on the customSDP string.
sys.SetCustomContent(customSDP)
sys.Dial("1234@somewhere.com")
Re: Different codecs for different VSP
Probably it would be easier to split SDP into lines and then rebuild again:Aaron wrote:customSDP = req.Body
#Do some fancy manipulations on the customSDP string.
sys.SetCustomContent(customSDP)
Code: Select all
sdp = req.Body.split("\r\n")
# ... manipulate the lines
sys.SetCustomContent(sdp.join("\r\n")
Question: in order to change codec preference, is it enough to rearrange payload types in the m=* string or I also need to resort a=rtpmap lines in order as they appear in the m=* line?
Re: Different codecs for different VSP
Yes, it's enough.MikeTelis wrote: Question: in order to change codec preference, is it enough to rearrange payload types in the m=* string or I also need to resort a=rtpmap lines in order as they appear in the m=* line?
a=rtpmap lines may be even missing in SDP if they are "describing" static payload types (per RFC4566).
Re: Different codecs for different VSP
Unfortunately, my quick experiments proven it wrong. Here is the original SDP:AndrewZ wrote:Yes, it's enough.
a=rtpmap lines may be even missing in SDP if they are "describing" static payload types (per RFC4566).
Code: Select all
o=- 141683 141683 IN IP4 192.168.1.33
s=-
c=IN IP4 192.168.1.33
t=0 0
m=audio 16480 RTP/AVP 18 0 2 4 8 96 97 98 100 101
a=rtpmap:18 G729a/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:2 G726-32/8000
a=rtpmap:4 G723/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:96 G726-40/8000
a=rtpmap:97 G726-24/8000
a=rtpmap:98 G726-16/8000
a=rtpmap:100 NSE/8000
a=fmtp:100 192-193
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=ptime:30
a=sendrecv
So, I believe we need to rearrange both m= and a= but... let's see what the guru (Aaron) says
Just in case you wish to experiment, here is my code:
Code: Select all
sdp = req.Body.split("\r\n").map do |line|
if line =~ /^(m=audio)\s+(\d+)\s+RTP\/AVP\s+(.+)$/
line = "#$1 #$2 RTP/AVP 0 18 2 4 8 96 97 98 100 101"
end
line
end.join("\r\n")
sys.SetCustomContent(sdp)
Re: Different codecs for different VSP
Try different provider.
Some VSPs are ignoring your preference order and providing connection using their own preferences but keeping in mind your capabilities.
Some VSPs are ignoring your preference order and providing connection using their own preferences but keeping in mind your capabilities.
Re: Different codecs for different VSP
I've been experimenting with Voxalot's echo test (*600).
Note what I said in my previous post: they did switch to u-Law once I changed the order of a=* lines.
Anyway, I have written a chunk of code implementing the algorithm:
The codecs in 2nd parameter must be in upper case. Critics are welcome!
Note what I said in my previous post: they did switch to u-Law once I changed the order of a=* lines.
Anyway, I have written a chunk of code implementing the algorithm:
Code: Select all
CRLF = "\r\n"
def set_codec_priority(sdp, order)
lines = sdp.split(CRLF)
pos = 0; pt = {}; codecs = {}; port = ''; m = []; newsdp = []
lines.each_with_index do |ln, i|
case ln
when /^m=audio\s+(\d+)\s+RTP\/AVP\s+(.+)$/
port = $1; m = $2.split(/\s+/).map {|x| x.to_i}; pos = i
when /^(a=(rtpmap|fmtp):(\d+)\s+(((.+)\/.+)|.*))$/
n = $3.to_i; pt[n] ||= [];
pt[n] << $1; codecs[$6.upcase] = n if $6
else newsdp << ln
end
end
# Find PTs for requested codecs, remove codecs not listed in original m=*
requested = order.gsub(/\s+/,'').split(',').map{|x| codecs[x]}.compact
m = requested + (m-requested) # Put requested codecs in front
( newsdp[0,pos] + ["m=audio #{port} RTP/AVP #{m.join(' ')}"] +
m.map {|x| pt[x]}.flatten + newsdp[pos-1,200]
).join(CRLF)
end
sys.SetCustomContent(set_codec_priority(req.Body, 'PCMA, PCMU, G729A, ILBC'))