Early Media Video Preview


We are testing some Fanvil and Akuvox video doorbells and trying to get the Video Preview to work on a Yealink phone while the call is still ringing.

As soon as we press ‘preview’ on the phone, we see that the phone sends to Asterisk a 183 with an SDP, but Asterisk does not “forward” the request to the doorbell.

We have tried enabling inband_progress = yes on the doorbell endpoint, but no luck…

What are we missing?


1 Like

Early media with video comes up every few months at this point, and it’s not something anyone has invested time into. It’s not supported. There is supposed to be code to handle certain situations, but it doesn’t seem to work, or things need to be implemented elsewhere.


Interesting. Thanks Josh.

So I guess the only way to have this working is by doing IP to IP calling.
Is there even a possibility for this to work with direct media? Or Asterisk must be involved with the initial stream setup?

If anyone does it differently, please speak up. Thank you :pray:

SDP negotiation and media flow still initially occurs between Asterisk and the endpoint. Direct media would have no impact.

This topic has been brought up on the Asterisk forum several times. I’m not certain if anyone got a solution, but app_dial does not have any code to handle video.

How many endpoints are you ringing? I seem to remember that Dial will use an early media bridge, rather than its own relay code, when there is only a single destination, so might be more likely to relay early video, in that case.

I should also point out that Asterisk is a back to back user agent, and does not forward SIP requests as such. 183 would be turned into AST_CONTROL_PROGRESS, which has no information about specific media types. This is what actually puts DIal into early media bridge mode, but only if there is only a single destination being called and only if no Dial options for ring back or music on hold, have been set (caller is not being entertained).

There are some rules, I believe, about having to have explicitly called the Progress() application, but that might be what the inband_progress option does.

One endpoint. 5507 (the doorbell) dials 66413 (the Yealink phone)

See the call log:

[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] pbx.c: Executing [[email protected]:54] Dial("PJSIP/5507-00000005", "PJSIP/66413/sip:[email protected]:5060,,HhTtrb(func-apply-sipheaders^s^1)") in new stack
[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] app_stack.c: PJSIP/66413-00000006 Internal Gosub(func-apply-sipheaders,s,1) start
[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] pbx.c: Executing [[email protected]:1] NoOp("PJSIP/66413-00000006", "Applying SIP Headers to channel PJSIP/66413-00000006") in new stack
[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] pbx.c: Executing [[email protected]:2] Set("PJSIP/66413-00000006", "TECH=PJSIP") in new stack
[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] pbx.c: Executing [[email protected]:3] Set("PJSIP/66413-00000006", "SIPHEADERKEYS=") in new stack
[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] pbx.c: Executing [[email protected]:4] While("PJSIP/66413-00000006", "0") in new stack
[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] app_while.c: Jumping to priority 10
[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] pbx.c: Executing [[email protected]:11] Return("PJSIP/66413-00000006", "") in new stack
[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] app_stack.c: Spawn extension (from-internal, 66413, 1) exited non-zero on 'PJSIP/66413-00000006'
[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] app_stack.c: PJSIP/66413-00000006 Internal Gosub(func-apply-sipheaders,s,1) complete GOSUB_RETVAL=
[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] app_dial.c: Called PJSIP/66413/sip:[email protected]:5060
[2022-08-19 12:05:53] VERBOSE[3479170][C-00000004] app_dial.c: PJSIP/66413-00000006 is ringing
[2022-08-19 12:05:56] VERBOSE[3479170][C-00000004] app_dial.c: PJSIP/66413-00000006 is making progress passing it to PJSIP/5507-00000005

But from what we see, it doesn’t actually pass it to 5507

Dial doesn’t, itself, generate AST_CONTROL_PROGRESS if it uses an early bridge, and, as I said, will throw away video frames if it bridges internally,. I haven’t checked ast_channel_early_bridge(), to see if that send AST_CONTROL_PROGRESS, but I think the log messages dates from before the big bridging rework, so was added before ast_channel_early_bridge() ever existed.

Dial is actually being naughty, as it is not testing whether ast_channel_early_bridge failed. It is possible that there are reasons that would not be picked up by the preceding macro call.

In any case ast_channel_early_bridge is very small, and all the work is done by the channel driver of, in this case, the caller’s channel, so the behaviour may differ between chan_sip and chan_pjsip.

Hi David, thanks for your response.

Not sure I fully understand this. Are you saying that if we see in the log PJSIP/66413-00000006 is making progress passing it to PJSIP/5507-00000005 it means that “something” (like inband_progress) has done the early bridges?

If you are referring to the dates of the logs I have posted above, it is from the past Friday.

Thinking if it is worth a shot trying this with chan_sip…


There hasn’t been any change to early bridging in Dial(). It doesn’t use the newer bridging framework for early media, it uses the same thing it has used probably since the dawn of its existence. It’s all done inside of it.

I’m afraid that is not true. Although it looks like Google found a fork above, the official github source code for release 18 (and master) clearly shows it calling ast_channel_early_bridge():

The ast_channel_early_bridge function isn’t the new bridging framework, it actually predates it. It is what is used for the “directrtpsetup” functionality in chan_sip. This is not implemented for chan_pjsip, and calling that will do nothing.

De facto, it means the Dial() application has received AST_CONTROL_PROGRESS from the outgoing channel driver. AST_CONTROL_PROGRESS is generated by the channel drivers for SIP when they receive a 183 response, but none of the other information from the response is included.

Historically, DIal, would have called ast_indicate, on the incoming side, with AST_CONTROL_PROGRESS, if there were no contraindications. The current versions seem to have the option of calling ast_channel_early_bridge, without indicating PROGRESS, although JColp has challenged that.

Some time, over five years ago, there was a big rewrite of the internals of bridging in Asterisk. Before that the only option for DIal was to do the early media bridging itself.

This is speculation, but it is possible that the change was tested on chan_sip and it was overlooked that it didn’t work on chan_pjsip.


Assuming that the macro will prevent this path being taken, it looks like most of what forwarding progress means is related to DAHDI channels, with Dial itself generating the tone signals, at a low level. It looks like, with SIP, it will only indicate progress if it was previously indicating ringing, although I’ve not checked that assumption in detail.

However, the key point is that Dial does not early bridge video, so regardless as to whether or not it has sent an indication that it is prepared to accept early media, video will not work.

If video is received from the callee, and it is the only callee, then it is supposed to be forwarded to the caller[1]. Same applies for the caller to callees direction too[2].

[1] asterisk/app_dial.c at master · asterisk/asterisk · GitHub
[2] asterisk/app_dial.c at master · asterisk/asterisk · GitHub

I think my problem there was that Google gave me a fork that didn’t support AST_FRAME_VIDEO, and I didn’t recheck on the main github. Oops.

Note that the second link indicates that video will be suppressed if Dial has been requested to send ringback before the callee indicates ringing, or it has been requested to send music on hold. The music or ringback will take precedence over early media.

Looking more closely the early_bridge call doesn’t terminate the processing of PROGRESS, so it doesn’t matter if the macro correctly indicates that the feature isn’t available.

The only place the code is actually doing anything that would cause the channel driver to send 183 is actually conditional on DIal not having been asked to send ringback before it receives RINGING. As you only have a single outgoing channel, the behaviour you are getting, assuming an Asterisk that is recent enough to forward video, is consistent with your having asked to return ringback to the doorbell before the callee has indicated ringback.

According to your log, you are, in fact, asking Dial to send ringback before it gets RINGING, although I don’t know FreePBX well enough to know where that is coming from. See the r option, in the following.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.