Using 2 Video Codecs with one PJSIP endpoint

Hello,
My project uses Asterisk 14 with PJSIP. The project has a need for an single endpoint (endpoint A) to receive both h264 and a vp8 video. Currently, I am using pjsip and my endpoint profile for (endpoint A) is configured to allow h264 and vp8, while the callers endpoint (endpoint B and C) is configured strictly for either h264 or vp8 respectively.

The problem is that Endpoint A is capable of receiving video from endpoint B (h264) or C (vp8), however only the first codec in the list of allowed codecs in the profile for Endpoint A is transmitted back. This means, if H264 is first allowed codec in the profile for Endpoint A, two way video only occurs if the caller is Endpoint B. If the caller is Endpoint C (vp8), endpoint A will receive the video, but endpoint C will not.

I understand that pjsip handles the video incoming and outgoing video feeds independently of each other. What I presume is occurring, is that the outgoing video feed is using the first codec in the profile and never switching to the second.

Would anyone have any ideas on how to resolve this issue?

You may be able to use the PJSIP_SEND_SESSION_REFRESH[1] dialplan function to send a re-invite to endpoint A to restrict it to the given codec of the called party. I haven’t tested it but it may accomplish what you want. Outside of that there is no mechanism to really allow this currently.

[1] https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Function_PJSIP_SEND_SESSION_REFRESH

Thank you for the reply. I was afraid of that response, I have tried using PJSIP_SEND_SESSION_REFRESH and PJSIP_MEDIA_OFFER without success.

We noticed that there is no SDP video codec negotiation happening between endpoints. Is this typical behavior of Asterisk? Is there a way to enforce asterisk video negotiation?

The behavior witness in our packet captures is as follows:
Asterisk handshakes with the caller, agreeing to use VP8. Asterisk then completely independently reaches out to the callee and agrees to use h264, based on the profile the callee has registered to. Asterisk then connects the two, resulting in 1 way video to the callee whose sip phone can decode vp8. The caller on the other hand, receives h264 video which it cannot decode, nor could it as its video feed is already open with a vp8 channel.

There is no current easy mechanism to reinvite or ensure that each side matches, except for the configuration.

Thank you for the quick response! This functionality is a pivotal need for this project and if it comes to it, the functionality may need to be custom coded. What do you think the LOE would be for this and would such a function impact other components? Do you think that is something Asterisk professional support could help with?

I was able to find a work-around solution using yours and others input. Hopefully this will help someone else that requires the ability to dynamically communicate through different video codecs and for anyone coming across this solution, feel free to improve it.

When a caller comes in to the PBX, they are run through an IVVR menu which will place them in a Queue to be connected with an agent. While in this initial IVVR menu, the following code is placed:

  ;This part retrieves the pjsip SDP video codecs from the caller
        exten => start,8,Set(codec=${PJSIP_MEDIA_OFFER(video)})
  ;This part looks at the variable and determines which codec is first, if vp8 or vp9, we go to VP8 subroutine, else we assume H264 and go to h264 subroutine.
         ;Match for vp8/vp9 preferred codec if present in the SDP offer, if it is not the first codec, move to next
                exten => start,9,GotoIf($[$["${codec:0:3}" = "vp9"] | $["${codec:0:3}" = "vp8"]]?if_vp8,1)
                ;Match for h264 preferred codec if present in the SDP offer, if it is not present, agent is not capable of receiving call and progresses to next line in dial plan. (or set :context,extension,priority) to send caller to another part of dial plan.
                exten => start,10,GotoIf($[$["${codec:0:4}" = "h264"]]?if_h264,1)
This is the subroutine the caller will go to, based on the determination above
exten => if_vp8,1,NoOp()
 same => n,Set(codec=vp8)
 same => n,Queue(QueueA,,,,,,,1(codecid^if_vp8^1)) ;Queues caller with instructions to run extension if_vp8 from codecid context when coming out of queue and connecting to agent.

exten => if_h264,1,NoOp()
 same => n,Set(codec=h264)
 same => n,Queue(QueueA,,,,,,,1(codecid^if_h264^1)) ;Queues caller with instructions to run extension if_h264 from codecid context when coming out of queue and connecting to agent.

This is the context codecid which has the code to be executed when the caller is dropped out of the queue, as per the instructions given in extensions ‘if_vp8’ or ‘if_h264’.

[codecid]
exten => if_vp8,1,NoOp()
 same => n,Set(codec=vp8) ;manually set variable
 same => n,Set(PJSIP_MEDIA_OFFER(video)=!all,${codec}) ;set invite with defined variable
 same => n,Set(PJSIP_SEND_SESSION_REFRESH()=invite) ;send invite with variable
 same => n,Return()

exten => if_h264,1,NoOp()
 same => n,Set(codec=h264) ;manually set variable
 same => n,Set(PJSIP_MEDIA_OFFER(video)=!all,${codec}) ;set invite with defined variable
 same => n,Set(PJSIP_SEND_SESSION_REFRESH()=invite) ;send invite with variable
 same => n,Return()

Need to update this, after the 14.4 upgrade the following code:
Set(PJSIP_MEDIA_OFFER(video)=!all,${codec})
Will actually strip the audio codec in the invite for the called party causing a no audio condition until paused/unpaused (sending reinvite with audio).
Instead do not declare deny all and use:
Set(PJSIP_MEDIA_OFFER(video)=${codec})

Hi,

I’m in the very same situation but I’m not so expert in Asterisk configuration.
Could someone please explain me which files need to be edited to add the code proposed by JohnE1 ?

Thank you!

The file from which you quoted the text that he modified.

I never quoted any text in my post. Which files need to be edited? Thank you

I got confused about who started the thread.

However, if you are unable to identify the file, you don’t know enough about Asterisk to be supported on a peer support basis.

I understand that but it seems quite reasonable to me to just asking for pointing me in the right direction.

I’m working on extensions_custom.conf but I don’t know if it’s the right files and actually it’s quite hard to debug, maybe there’re some istructions I can add to the code to add log lines just to understand if my code is getting called ?

Thank you.

It seems you are trying to modify a FreePBX system. Asterisk does not know about extensions_custom.conf unless it is included by some other file as a result of user or third party configuration . The complexity comes from FreePBX which also added the include referencing extensions_custom.conf.

FreePBX peer support can be obtained from https://community.freepbx.org/ although I suspect you may have to abandon FreePBX.

extensions.conf is so fundamental to Asterisk configuration, that anyone using it directly (or attempting to extend FreePBX) should be extremely familiar with it.)

2 Likes