Skip to content

2026.8.1-dev pre-release: consolidated calls and the P4 videophone

Pre-release
Pre-release

Choose a tag to compare

@n-IA-hane n-IA-hane released this 25 Jul 18:56
· 0 commits to aafcaee570d5778fba82cfbf4bab084f88e0dc1c since this release

2026.8.1-dev pre-release: consolidated calls and the P4 videophone

2026.8.1-dev remains an active pre-release and work in progress. The tag and
HACS archive may be refreshed while field qualification continues. Use
2026.8.0 when you need the current stable release.

🏠 Home Assistant and VoIP Stack

  • The Home Assistant audio and video media paths now share one lifecycle for
    authenticated ownership, replacement barriers, live-session resolution,
    bridge leases, cleanup and final state publication.
  • Physical ESPHome phones and Home Assistant softphones now use the same
    device_id source selector. The service dispatches each phone through its
    native adapter, and an ESP service response is no longer resolved again as
    a browser phone.
  • The new packages/voip/ha_phone.yaml package provides the complete physical
    phone surface in one include: discovery entities, native call-control
    actions and the Home Assistant managed phonebook.
  • SIP routing identity and presentation identity remain separate. Stable URI
    users route calls, while standard quoted display names preserve spaces from
    ESP friendly names, local accounts and external callers. RFC 4916 connected
    identity lets the caller learn the resolved callee after answer.
  • SIP-to-SIP bridges negotiate each leg independently. Compatible codecs stay
    on direct RTP, while the optional bounded FFmpeg fallback converts an
    incompatible active direction to H.264, VP8 or RTP/JPEG as required by the
    receiving endpoint.
  • An established audio call can add, remove and add video again through
    standard in-dialog re-INVITE without restarting its audio relay. RTP profile,
    direction, payload type and codec changes commit as one media generation.
  • Transcoded SIP audio is paced by its negotiated packet time, and immediate
    redial waits for the previous bounded transcoder to release its slot.
  • Negotiated RFC 4733 DTMF payload types and media direction are retained
    through direct, bridged and trunk call paths.
  • Browser ownership follows the logical phone, committed SIP transaction,
    active call and media direction. Dashboard reloads and multiple cards can
    hand media over without creating a second call owner.
  • Mixed browser and SIP ring groups let the first valid answer win, cancel the
    losing INVITEs and settle every remaining leg.
  • Inbound routing, forwarding, conference ringing, SIP bridge handling and
    browser media claims now use focused lifecycle owners while CallRegistry
    remains the observable compatibility index.
  • In-dialog video activation now follows the bridge relay that is actually active, not merely the presence of a dormant recvonly SDP media line. Re-INVITEs preserve the negotiated RTP audio codec and payload instead of accidentally changing PCMA, PCMU, G.722 or Opus into L16.
  • Completed dialogs retain a bounded SIP transaction tombstone. A delayed retransmission of the original INVITE now receives 481 Call/Transaction Does Not Exist and cannot reclaim a softphone after BYE.
  • Unexpected teardown failures are surfaced instead of being silently hidden,
    and completed calls release their sessions, sockets, bridges and RTP ports.
  • FRITZ!Box REGISTER now uses the bare registrar URI, keeps the account AOR in
    To and From, refreshes CSeq and Via branch after authentication, follows SIP
    Timer F and runs without blocking Home Assistant setup.
  • FRITZ!Box interoperability has been improved for authenticated registration
    and internal service dial strings such as **621. Thanks to
    @ruedigerhanses-stack for the careful hardware testing and iterative
    validation in issue #95.
  • RTP audio with valid packet boundaries different from negotiated ptime is
    accumulated and reframed by the shared PCM converter. This fixes the
    reported FRITZ!Box PCMA/16000 320-byte input without forcing a codec change.
  • ESPHome phonebook delivery now tracks exact content per device. Reconnects
    restore only the restarted phone, while duplicate callbacks and unchanged
    setup retries no longer republish the roster to every ESP.

🎬 Browser video worker and card

  • JPEG encoding and decoding, plus H.264 and VP8 WebCodecs decoding when the
    browser supports it, can run in a dedicated worker instead of blocking the
    card UI.
  • Worker generations prevent stale frames from a replaced call from reaching
    the screen. VideoFrame and ImageBitmap objects are closed on success,
    replacement and error paths.
  • The card editor and view builder are now focused modules without changing
    the public card configuration.
  • The card remains the GUI and media surface of a logical softphone. The
    softphone itself continues to exist and ring independently of an open card.
  • Browser calls verify secure context, Web Audio support and microphone access
    before signaling. A web view without getUserMedia no longer accepts a call
    and immediately tears it down with BYE.
  • Thanks to @csfrussa, browser microphone downsampling now applies a
    fourth-order Butterworth anti-alias filter before decimation. In Chromium
    validation it reduced a 12 kHz tone folding into 4 kHz by 23.4 dB while the
    wanted 1 kHz signal remained unchanged.
  • A Microphone anti-alias filter switch in the card's idle Options panel
    lets each browser and logical phone compare the filtered and legacy paths.
    It is enabled by default, applies from the next call and adds no filtering
    cost when the browser and negotiated transmit rates already match.

A live P4 camera call in the Home Assistant softphone card

🎥 WE HAVE A F...ING ESPHOME VIDEOPHONE!

Everything started when @Psix-anp shared a working ESP32-P4 camera build based
on the ESPHome camera work by @youkorr. What can I say, half a second later I
was already experimenting with bidirectional SIP video on ESPHome.

And we made it. A P4 can now be a real audio and video SIP endpoint, including
bidirectional video on its own display. Better still, the JPEG path is light
enough to live inside the full P4 profile alongside Micro Wake Word, Voice
Assistant, AFE echo cancellation, LVGL, TTS and Sendspin.

This opens the door to custom ESPHome videophones and doorbells with echo
cancellation, full P4 voice-assistant tablets, and direct room-to-room audio
and video calls between P4 devices.

Two P4 videophone use cases, a door call and a room-to-room call

The implementation stays close to the accelerated Espressif media paths:

  • esp_video 2.3.0 owns the MIPI-CSI and V4L2 camera pipeline. JPEG SIP TX
    borrows the camera's already encoded access unit, so it does not capture or
    encode the same frame a second time.
  • The JPEG camera follows Espressif's V4L2 startup practice and discards the
    first two CSI buffers after STREAMON. Cross-codec calls therefore begin
    with a color-stable JPEG and VP8 keyframe instead of publishing a transient
    ISP startup frame.
  • The H.264 profile uses esp_h264 1.3.6 for the ESP32-P4 hardware encoder and
    software decoder, with esp_image_effects 1.1.0 for its optimized I420
    conversion.
  • ESP-IDF PPA handles scaling, rotation and color conversion. Hardware JPEG
    decode and direct MIPI DSI presentation keep the P4 display path lean.
  • JPEG and H.264 are gated at compile time. A JPEG firmware does not include
    the H.264 media path, and the H.264 firmware does not include JPEG SIP video.

The P4 profiles are now:

  • the canonical full AFE JPEG videophone,
    waveshare-p4-touch-full-afe-landscape-videophone-jpeg.yaml;
  • the lightweight bidirectional RTP/JPEG videophone,
    waveshare-p4-touch-videophone-jpeg.yaml;
  • the experimental bidirectional H.264 videophone,
    waveshare-p4-touch-videophone-h264.yaml.

H.264 remains experimental in this pre-release. JPEG is the current full P4
baseline.

⌨️ Smaller ESPHome improvements

The compact Spotpear profile now has a dedicated touch keypad that keeps
contact navigation and direct extension dialing on the device.

The Spotpear touch keypad

Existing ESP audio profiles keep their native PCM transport and audio-stack
behavior. This update does not replace the audio backend or reduce configured
sample rates. P4 codec selection remains compile-time gated and its media tasks
remain event driven.

⚠️ Breaking change

The former P4 full landscape profile was promoted to the canonical full JPEG
videophone and renamed:

yamls/full-experience/single-bus/waveshare-p4-touch-full-afe-landscape.yaml

is now:

yamls/full-experience/single-bus/waveshare-p4-touch-full-afe-landscape-videophone-jpeg.yaml

Review the complete
breaking changes
before updating an existing installation.

✅ Qualification

  • 1351 Python tests plus 126 subtests passed.
  • Ruff passed for the custom component, ESPHome components, tests and tools.
  • Every shipped JavaScript file passed syntax validation.
  • The canonical full JPEG profile completed repeated real HA-to-P4 calls with
    bidirectional audio and video, zero reported RTP loss or media drops, clean
    BYE handling and quiescent call-scoped resource cleanup.
  • A Zoiper-style PCMA and VP8 call completed audio-to-video re-INVITE through
    the HA B2BUA and its JPEG fallback. The first returned VP8 frame was a valid,
    color-stable keyframe; all four audio/video RTP flows reported zero packet
    loss and both JPEG depacketizers reported zero dropped access units.
  • The dedicated JPEG and experimental H.264 P4 profiles have both completed
    real bidirectional audio and video calls on hardware.
  • Real voip_stack.call service tests originated calls from P4 to WS3 and
    from WS3 to P4 using their Home Assistant Device IDs. Both directions
    reached in_call, returned the physical ESP source descriptor and cleaned
    both endpoints back to idle after hangup.
  • Ten consecutive real SIP cycles completed audio to video to audio renegotiation, bidirectional RTP, immediate redial and BYE / 200 OK. A real card-originated call succeeded immediately after the tenth cleanup.
  • The final hardware matrix completed 12 calls across P4, WS3 and a real
    trunk, including H.264 audio-video-audio-video renegotiation, SIP INFO and
    RFC 2833 DTMF, hangup from both directions, immediate redial and zero
    call-scoped resources after cleanup.

💖 Si ringrazia per le donazioni

Un grazie speciale a @jjhelin, @kuid87 e @jftkcs per aver sostenuto il
progetto. Se VoIP Stack ti è stato utile e vuoi contribuire al suo sviluppo,
puoi farlo tramite GitHub Sponsors.

📦 Installation and feedback

In HACS, enable pre-release versions for VoIP Stack. Open VoIP Stack, use the
three-dot menu, select Redownload and choose 2026.8.1-dev. Restart Home
Assistant, then clear the browser or Companion app cache so the updated card
multimedia engine is loaded.

When reporting a regression, include the exact test time, call direction,
endpoint models, selected codec and sanitized logs from INVITE through final
cleanup. The GitHub release contains the flat voip_stack.zip archive used by
HACS.