Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package baresip for openSUSE:Factory checked 
in at 2026-10-01 16:41:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/baresip (Old)
 and      /work/SRC/openSUSE:Factory/.baresip.new.1253 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "baresip"

Thu Oct  1 16:41:58 2026 rev:21 rq:1381731 version:4.12.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/baresip/baresip.changes  2026-09-09 
16:23:55.158957713 +0200
+++ /work/SRC/openSUSE:Factory/.baresip.new.1253/baresip.changes        
2026-10-01 16:41:59.953350125 +0200
@@ -1,0 +2,20 @@
+Wed Sep 30 18:03:35 UTC 2026 - Martin Hauke <[email protected]>
+
+- Update to version 4.12.0
+  * Feature: Send Custom X-Headers on Outbound Calls.
+  * audio: thread-safe usage of psize and ptime in tx_thread().
+  * jbuf: safer jbuf_set_id.
+  * audio: add mutex lock for aubuf statistics.
+  * test: add testing of peerconn and vidfilt.
+  * audio: fix format name in ausrc format mismatch warning.
+  * test: fix peerconn and vidfilt.
+  * cmake: use variable for libdir libbaresip.pc.in
+  * aureceiver: stats cleanup.
+  * rtprecv: tiny cleanup for startup.
+  * rtprecv: add stop flag fixes race condition.
+  * auresamp: alloc for implicit format conversion.
+  * aureceiver: fix decoder sample format and cleanup.
+  * audio: use RE_ATOMIC for muted flag.
+  * gst,play: fix err handling.
+
+-------------------------------------------------------------------
@@ -19,0 +40,6 @@
+
+-------------------------------------------------------------------
+Fri Aug  7 20:39:11 UTC 2026 - Luigi Baldoni <[email protected]>
+
+- Remove Provides/Obsoletes lines from library subpackage in
+  order to avoid uninstallation of main package at every update.

Old:
----
  baresip-4.11.0.tar.gz

New:
----
  baresip-4.12.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ baresip.spec ++++++
--- /var/tmp/diff_new_pack.4m7Ouy/_old  2026-10-01 16:42:01.522415895 +0200
+++ /var/tmp/diff_new_pack.4m7Ouy/_new  2026-10-01 16:42:01.535416440 +0200
@@ -17,10 +17,10 @@
 #
 
 
-%global sover   28
+%global sover   29
 %global libname lib%{name}%{sover}
 Name:           baresip
-Version:        4.11.0
+Version:        4.12.0
 Release:        0
 Summary:        Modular SIP useragent
 License:        BSD-3-Clause
@@ -119,8 +119,6 @@
 
 %package -n %{libname}
 Summary:        Standard library for baresip
-Provides:       %{name} = %{version}-%{release}
-Obsoletes:      %{name} < %{version}-%{release}
 
 %description -n %{libname}
 This package contains the shared library needed to run programs compiled with

++++++ baresip-4.11.0.tar.gz -> baresip-4.12.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/.github/workflows/build.yml 
new/baresip-4.12.0/.github/workflows/build.yml
--- old/baresip-4.11.0/.github/workflows/build.yml      2026-08-24 
13:09:33.000000000 +0200
+++ new/baresip-4.12.0/.github/workflows/build.yml      2026-09-30 
19:40:56.000000000 +0200
@@ -89,7 +89,6 @@
       run: |
         brew install codec2 \
                         aom \
-                        fdk-aac \
                         ffmpeg \
                         jack \
                         spandsp \
@@ -134,7 +133,7 @@
     - name: baresip static
       run: |
         rm -Rf build-static
-        cmake -B build-static -DSTATIC=1 -DCMAKE_C_FLAGS="-Werror" 
-DMODULES="g711;l16;ausine;fakevideo;auconv;auresamp;dtls_srtp;srtp;aufile;ice;mixausrc"
+        cmake -B build-static -DSTATIC=1 -DCMAKE_C_FLAGS="-Werror" 
-DMODULES="g711;l16;ausine;fakevideo;auconv;auresamp;dtls_srtp;srtp;aufile;ice;mixausrc;selfview;vidinfo"
         cmake --build build-static -j
 
     - name: selftest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/.github/workflows/coverage.yml 
new/baresip-4.12.0/.github/workflows/coverage.yml
--- old/baresip-4.11.0/.github/workflows/coverage.yml   2026-08-24 
13:09:33.000000000 +0200
+++ new/baresip-4.12.0/.github/workflows/coverage.yml   2026-09-30 
19:40:56.000000000 +0200
@@ -43,7 +43,7 @@
       run: sudo ldconfig
 
     - name: make baresip selftest
-      run: cmake -B build -DSTATIC=1 -DCMAKE_C_FLAGS="--coverage" 
-DCMAKE_EXE_LINKER_FLAGS="--coverage" 
-DMODULES="g711;l16;ausine;fakevideo;auconv;auresamp;dtls_srtp;srtp;aufile;ice;mixausrc"
 && cmake --build build -j
+      run: cmake -B build -DSTATIC=1 -DCMAKE_C_FLAGS="--coverage" 
-DCMAKE_EXE_LINKER_FLAGS="--coverage" 
-DMODULES="g711;l16;ausine;fakevideo;auconv;auresamp;dtls_srtp;srtp;aufile;ice;mixausrc;selfview;vidinfo"
 && cmake --build build -j
 
     - name: selftest
       run: ./build/test/selftest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/.github/workflows/sanitizers.yml 
new/baresip-4.12.0/.github/workflows/sanitizers.yml
--- old/baresip-4.11.0/.github/workflows/sanitizers.yml 2026-08-24 
13:09:33.000000000 +0200
+++ new/baresip-4.12.0/.github/workflows/sanitizers.yml 2026-09-30 
19:40:56.000000000 +0200
@@ -58,7 +58,7 @@
       run: sudo ldconfig
 
     - name: make baresip selftest
-      run: cmake -B build -DHAVE_THREADS= -DSTATIC=1 
-DMODULES="g711;l16;ausine;fakevideo;auconv;auresamp;dtls_srtp;srtp;aufile;ice;mixausrc"
 && cmake --build build -j
+      run: cmake -B build -DHAVE_THREADS= -DSTATIC=1 
-DMODULES="g711;l16;ausine;fakevideo;auconv;auresamp;dtls_srtp;srtp;aufile;ice;mixausrc;selfview;vidinfo"
 && cmake --build build -j
 
     - name: run selftest
       run: ./build/test/selftest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/.github/workflows/valgrind.yml 
new/baresip-4.12.0/.github/workflows/valgrind.yml
--- old/baresip-4.11.0/.github/workflows/valgrind.yml   2026-08-24 
13:09:33.000000000 +0200
+++ new/baresip-4.12.0/.github/workflows/valgrind.yml   2026-09-30 
19:40:56.000000000 +0200
@@ -40,7 +40,7 @@
       run: sudo ldconfig
 
     - name: make baresip selftest
-      run: cmake -B build -DSTATIC=1 
-DMODULES="g711;l16;ausine;fakevideo;auconv;auresamp;dtls_srtp;srtp;aufile;ice;mixausrc"
 && cmake --build build -j
+      run: cmake -B build -DSTATIC=1 
-DMODULES="g711;l16;ausine;fakevideo;auconv;auresamp;dtls_srtp;srtp;aufile;ice;mixausrc;selfview;vidinfo"
 && cmake --build build -j
 
     - name: valgrind test
       run: valgrind --leak-check=full --show-reachable=yes --error-exitcode=42 
./build/test/selftest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/CHANGELOG.md 
new/baresip-4.12.0/CHANGELOG.md
--- old/baresip-4.11.0/CHANGELOG.md     2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/CHANGELOG.md     2026-09-30 19:40:56.000000000 +0200
@@ -5,9 +5,36 @@
 The format is based on [Keep a 
Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic 
Versioning](https://semver.org/spec/v2.0.0.html).
 
+## v4.12.0 - 2026-09-30
+
+### What's Changed
+* Feature: Send Custom X-Headers on Outbound Calls by @ajrice6713 in 
https://github.com/baresip/baresip/pull/3800
+* audio: thread-safe usage of psize and ptime in tx_thread() by @alfredh in 
https://github.com/baresip/baresip/pull/3810
+* jbuf: safer jbuf_set_id by @cspiel1 in 
https://github.com/baresip/baresip/pull/3809
+* audio: add mutex lock for aubuf statistics by @alfredh in 
https://github.com/baresip/baresip/pull/3812
+* test: add testing of peerconn and vidfilt by @alfredh in 
https://github.com/baresip/baresip/pull/3815
+* audio: fix format name in ausrc format mismatch warning by @allesrebel in 
https://github.com/baresip/baresip/pull/3820
+* ci: remove brew fdk-aac package (discontinued) by @alfredh in 
https://github.com/baresip/baresip/pull/3828
+* test: fix peerconn and vidfilt by @alfredh in 
https://github.com/baresip/baresip/pull/3816
+* cmake: use variable for libdir libbaresip.pc.in by @fictitiousexistence in 
https://github.com/baresip/baresip/pull/3832
+* aureceiver: stats cleanup by @cspiel1 in 
https://github.com/baresip/baresip/pull/3826
+* rtprecv: tiny cleanup for startup by @cspiel1 in 
https://github.com/baresip/baresip/pull/3825
+* rtprecv: add stop flag fixes race condition by @cspiel1 in 
https://github.com/baresip/baresip/pull/3838
+* auresamp: alloc for implicit format conversion by @cspiel1 in 
https://github.com/baresip/baresip/pull/3837
+* aureceiver: fix decoder sample format and cleanup by @cspiel1 in 
https://github.com/baresip/baresip/pull/3827
+* audio: use RE_ATOMIC for muted flag by @alfredh in 
https://github.com/baresip/baresip/pull/3839
+* gst,play: fix err handling by @cspiel1 in 
https://github.com/baresip/baresip/pull/3842
+
+## New Contributors
+* @ajrice6713 made their first contribution in 
https://github.com/baresip/baresip/pull/3800
+* @allesrebel made their first contribution in 
https://github.com/baresip/baresip/pull/3820
+* @fictitiousexistence made their first contribution in 
https://github.com/baresip/baresip/pull/3832
+
+**Full Changelog**: 
https://github.com/baresip/baresip/compare/v4.11.0...v4.12.0
+
 ## v4.11.0 - 2026-08-25
 
-## What's Changed
+### What's Changed
 * core: cleanup stream_rtp_h ignore handling by @sreimers in 
https://github.com/baresip/baresip/pull/3770
 * audio: increase RTP timestamp also for underruns by @cspiel1 in 
https://github.com/baresip/baresip/pull/3775
 * aubuf: remove adaptive mode by @cspiel1 in 
https://github.com/baresip/baresip/pull/3780
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/CMakeLists.txt 
new/baresip-4.12.0/CMakeLists.txt
--- old/baresip-4.11.0/CMakeLists.txt   2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/CMakeLists.txt   2026-09-30 19:40:56.000000000 +0200
@@ -13,9 +13,9 @@
 
 cmake_minimum_required(VERSION 3.18...4.0)
 
-project(baresip VERSION 4.11.0)
+project(baresip VERSION 4.12.0)
 
-set(PROJECT_SOVERSION 28) # bump if ABI breaks
+set(PROJECT_SOVERSION 29) # bump if ABI breaks
 
 # Pre-release identifier, comment out on a release
 # Increment for breaking changes (dev2, dev3...)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/docs/examples/accounts 
new/baresip-4.12.0/docs/examples/accounts
--- old/baresip-4.11.0/docs/examples/accounts   2026-08-24 13:09:33.000000000 
+0200
+++ new/baresip-4.12.0/docs/examples/accounts   2026-09-30 19:40:56.000000000 
+0200
@@ -50,6 +50,7 @@
 #    ;video_codecs=h264,vp8,...
 #    ;video_display=x11,nil
 #    ;video_source=v4l2,/dev/video0
+#    ;x_headers=Header-Name:value,Other-Header:value
 #
 # Examples:
 #
@@ -86,3 +87,8 @@
 
 
 # ... more examples can be added here ...
+
+#
+# Send static custom SIP headers on every outbound call from this account
+#
+<sip:[email protected]>;auth_pass=pass;x_headers=X-My-Header:value,X-Other:value
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/include/baresip.h 
new/baresip-4.12.0/include/baresip.h
--- old/baresip-4.11.0/include/baresip.h        2026-08-24 13:09:33.000000000 
+0200
+++ new/baresip-4.12.0/include/baresip.h        2026-09-30 19:40:56.000000000 
+0200
@@ -13,7 +13,7 @@
 
 
 /** Defines the Baresip version string */
-#define BARESIP_VERSION "4.11.0"
+#define BARESIP_VERSION "4.12.0"
 
 
 #ifndef NET_MAX_NS
@@ -151,6 +151,7 @@
 bool account_call_transfer(const struct account *acc);
 bool account_rtcp_mux(const struct account *acc);
 const char *account_extra(const struct account *acc);
+const struct list *account_custom_hdrs(const struct account *acc);
 int account_uri_complete_strdup(const struct account *acc, char **strp,
                                const struct pl *uri);
 int account_uri_complete(const struct account *acc, struct mbuf *buf,
@@ -1612,7 +1613,7 @@
 int jbuf_alloc(struct jbuf **jbp, uint32_t mind, uint32_t maxd,
               uint32_t maxsz);
 void jbuf_set_srate(struct jbuf *jb, uint32_t srate);
-void jbuf_set_id(struct jbuf *jb, struct pl *id);
+int  jbuf_set_id(struct jbuf *jb, const char *id);
 int  jbuf_set_type(struct jbuf *jb, enum jbuf_type jbtype);
 void jbuf_set_gnack(struct jbuf *jb, struct rtp_sock *rtp);
 int  jbuf_put(struct jbuf *jb, const struct rtp_header *hdr, void *mem);
@@ -1896,7 +1897,8 @@
                                   struct list *aucodecl, enum sdp_dir dir);
 int peerconnection_add_video_track(struct peer_connection *pc,
                                   const struct config *cfg,
-                                  struct list *vidcodecl, enum sdp_dir dir);
+                                  struct list *vidcodecl,
+                                  struct list *vidfiltl, enum sdp_dir dir);
 int  peerconnection_set_remote_descr(struct peer_connection *pc,
                                    const struct session_description *sd);
 int  peerconnection_create_offer(struct peer_connection *pc,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/mk/Doxyfile 
new/baresip-4.12.0/mk/Doxyfile
--- old/baresip-4.11.0/mk/Doxyfile      2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/mk/Doxyfile      2026-09-30 19:40:56.000000000 +0200
@@ -4,7 +4,7 @@
 # Project related configuration options
 #---------------------------------------------------------------------------
 PROJECT_NAME           = baresip
-PROJECT_NUMBER         = 4.11.0
+PROJECT_NUMBER         = 4.12.0
 OUTPUT_DIRECTORY       = ../baresip-dox
 CREATE_SUBDIRS         = NO
 OUTPUT_LANGUAGE        = English
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/modules/auresamp/auresamp.c 
new/baresip-4.12.0/modules/auresamp/auresamp.c
--- old/baresip-4.11.0/modules/auresamp/auresamp.c      2026-08-24 
13:09:33.000000000 +0200
+++ new/baresip-4.12.0/modules/auresamp/auresamp.c      2026-09-30 
19:40:56.000000000 +0200
@@ -162,8 +162,9 @@
        int err = 0;
 
        if (st->dbg) {
-               debug("auresamp: resample %s %u/%u --> %u/%u\n", st->dbg,
-                     af->srate, af->ch, st->oprm.srate, st->oprm.ch);
+               debug("auresamp: resample %s %u/%u (%s) --> %u/%u (%s)\n",
+                     st->dbg, af->srate, af->ch, aufmt_name(af->fmt),
+                     st->oprm.srate, st->oprm.ch, aufmt_name(st->oprm.fmt));
                st->dbg = NULL;
        }
 
@@ -177,14 +178,16 @@
                return 0;
        }
 
-       sampv  = af->sampv;
-       if (af->fmt != AUFMT_S16LE) {
+       if (af->fmt != AUFMT_S16LE || st->oprm.fmt != AUFMT_S16LE) {
                if (!st->sampv)
                        err = sampv_alloc(st, af);
 
                if (err)
                        return err;
+       }
 
+       sampv  = af->sampv;
+       if (af->fmt != AUFMT_S16LE) {
                auconv_to_s16(st->sampv, af->fmt, af->sampv, af->sampc);
                sampv = st->sampv;
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/modules/gst/gst.c 
new/baresip-4.12.0/modules/gst/gst.c
--- old/baresip-4.11.0/modules/gst/gst.c        2026-08-24 13:09:33.000000000 
+0200
+++ new/baresip-4.12.0/modules/gst/gst.c        2026-09-30 19:40:56.000000000 
+0200
@@ -98,11 +98,6 @@
                        g_free(d);
 
                        st->err = err->code;
-
-                       /* Call error handler */
-                       if (st->errh)
-                               st->errh(err->code, err->message, st->arg);
-
                        g_error_free(err);
 
                        st->run = false;
@@ -405,6 +400,9 @@
                        if (st->errh)
                                st->errh(0, "end of file", st->arg);
                }
+               else if (st->err && st->errh) {
+                       st->errh(st->err, "error", st->arg);
+               }
        }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/packaging/libbaresip.pc.in 
new/baresip-4.12.0/packaging/libbaresip.pc.in
--- old/baresip-4.11.0/packaging/libbaresip.pc.in       2026-08-24 
13:09:33.000000000 +0200
+++ new/baresip-4.12.0/packaging/libbaresip.pc.in       2026-09-30 
19:40:56.000000000 +0200
@@ -1,6 +1,6 @@
 prefix="@CMAKE_INSTALL_PREFIX@"
 exec_prefix=${prefix}
-libdir=${prefix}/lib
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
 includedir=${prefix}/include
 
 Name: libbaresip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/src/account.c 
new/baresip-4.12.0/src/account.c
--- old/baresip-4.11.0/src/account.c    2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/src/account.c    2026-09-30 19:40:56.000000000 +0200
@@ -48,6 +48,7 @@
        mem_deref(acc->extra);
        mem_deref(acc->uas_user);
        mem_deref(acc->uas_pass);
+       list_flush(&acc->custom_hdrs);
 }
 
 
@@ -472,6 +473,42 @@
 }
 
 
+static int xhdrs_decode(struct account *acc, const struct pl *prm)
+{
+       struct pl xhdrs;
+       char pair[256];
+       int err = 0;
+
+       if (msg_param_decode(prm, "x_headers", &xhdrs))
+               return 0;
+
+       while (0 == csl_parse(&xhdrs, pair, sizeof(pair))) {
+               struct pl name, val;
+               char *nbuf = NULL;
+
+               if (re_regex(pair, str_len(pair), "[^:]+:[~]+",
+                            &name, &val)) {
+                       warning("account: x_headers: bad pair '%s'"
+                               " (expected Name:Value)\n", pair);
+                       err = EINVAL;
+                       break;
+               }
+
+               err = re_sdprintf(&nbuf, "%r", &name);
+               if (err)
+                       break;
+
+               err = custom_hdrs_add(&acc->custom_hdrs, nbuf,
+                                     "%r", &val);
+               mem_deref(nbuf);
+               if (err)
+                       break;
+       }
+
+       return err;
+}
+
+
 static int sip_params_decode(struct account *acc, const struct sip_addr *aor)
 {
        struct pl auth_user;
@@ -613,6 +650,7 @@
        err |= video_codecs_decode(acc, &acc->laddr.params);
        err |= media_decode(acc, &acc->laddr.params);
        err |= param_bool(&acc->catchall, &acc->laddr.params, "catchall");
+       err |= xhdrs_decode(acc, &acc->laddr.params);
        if (err)
                goto out;
 
@@ -1911,6 +1949,19 @@
 
 
 /**
+ * Get the list of static custom SIP headers for an account
+ *
+ * @param acc User-Agent account
+ *
+ * @return List of custom SIP headers (struct sip_hdr)
+ */
+const struct list *account_custom_hdrs(const struct account *acc)
+{
+       return acc ? &acc->custom_hdrs : NULL;
+}
+
+
+/**
  * Auto complete a SIP uri, add scheme and domain if missing
  *
  * @param acc User-Agent account
@@ -2100,6 +2151,14 @@
                          dtmfmode_str(acc->dtmfmode));
        err |= re_hprintf(pf, " extra:            %s\n",
                          acc->extra ? acc->extra : "none");
+       if (!list_isempty(&acc->custom_hdrs)) {
+               err |= re_hprintf(pf, " x_headers:        ");
+               for (le = list_head(&acc->custom_hdrs); le; le = le->next) {
+                       const struct sip_hdr *h = le->data;
+                       err |= re_hprintf(pf, " %r:%r", &h->name, &h->val);
+               }
+               err |= re_hprintf(pf, "\n");
+       }
        err |= re_hprintf(pf, " fbregint:         %u\n", acc->fbregint);
        err |= re_hprintf(pf, " inreq_allowed:    %s\n",
                          inreq_mode_str(acc->inreq_mode));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/src/audio.c 
new/baresip-4.12.0/src/audio.c
--- old/baresip-4.11.0/src/audio.c      2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/src/audio.c      2026-09-30 19:40:56.000000000 +0200
@@ -96,7 +96,7 @@
        uint32_t ts_tel;              /**< Timestamp for Telephony Events  */
        size_t psize;                 /**< Packet size for sending         */
        bool marker;                  /**< Marker bit for outgoing RTP     */
-       bool muted;                   /**< Audio source is muted           */
+       RE_ATOMIC bool muted;         /**< Audio source is muted           */
        int cur_key;                  /**< Currently transmitted event     */
        enum aufmt src_fmt;           /**< Sample format for audio source  */
        enum aufmt enc_fmt;           /**< Sample format for encoder       */
@@ -528,27 +528,28 @@
 
        mtx_lock(tx->mtx);
        enum aufmt fmt = tx->src_fmt;
-       bool muted = tx->muted;
        size_t psize = tx->psize;
        mtx_unlock(tx->mtx);
 
        if (fmt != af->fmt) {
                warning("audio: ausrc format mismatch:"
                        " expected=%d(%s), actual=%d(%s)\n",
-                       fmt, aufmt_name(tx->src_fmt),
+                       fmt, aufmt_name(fmt),
                        af->fmt, aufmt_name(af->fmt));
                return;
        }
 
-       if (muted)
+       if (re_atomic_rlx(&tx->muted))
                auframe_mute(af);
 
        if (aubuf_cur_size(tx->aubuf) >= tx->aubuf_maxsz) {
 
-               ++tx->stats.aubuf_overrun;
+               mtx_lock(tx->mtx);
+               uint64_t aubuf_overrun = ++tx->stats.aubuf_overrun;
+               mtx_unlock(tx->mtx);
 
                debug("audio: tx aubuf overrun (total %llu)\n",
-                     tx->stats.aubuf_overrun);
+                     aubuf_overrun);
        }
 
        (void)aubuf_write_auframe(tx->aubuf, af);
@@ -872,6 +873,9 @@
                if (!re_atomic_rlx(&tx->thr.run))
                        break;
 
+               size_t psize = tx->psize;
+               uint32_t ptime = tx->ptime;
+
                mtx_unlock(tx->mtx);
 
                now = tmr_jiffies();
@@ -883,21 +887,21 @@
 
                /* Now is the time to send */
 
-               if (aubuf_cur_size(tx->aubuf) >= tx->psize) {
+               if (aubuf_cur_size(tx->aubuf) >= psize) {
 
                        poll_aubuf_tx(a);
                }
                else {
-                       ++tx->stats.aubuf_underrun;
                        mtx_lock(tx->mtx);
-                       tx->ts_ext += (tx->ptime * tx->ac->crate / 1000);
+                       uint64_t aubuf_underrun = ++tx->stats.aubuf_underrun;
+                       tx->ts_ext += (ptime * tx->ac->crate / 1000);
                        mtx_unlock(tx->mtx);
 
                        debug("audio: thread: tx aubuf underrun"
-                             " (total %llu)\n", tx->stats.aubuf_underrun);
+                             " (total %llu)\n", aubuf_underrun);
                }
 
-               ts += tx->ptime;
+               ts += ptime;
 
                /* Exact timing: send Telephony-Events from here.
                 * Be aware check_telev sets tx->mtx, so it must released!
@@ -1479,7 +1483,7 @@
        if (!a)
                return;
 
-       a->tx.muted = muted;
+       re_atomic_rlx_set(&a->tx.muted, muted);
 }
 
 
@@ -1495,7 +1499,7 @@
        if (!a)
                return false;
 
-       return a->tx.muted;
+       return re_atomic_rlx(&a->tx.muted);
 }
 
 
@@ -1650,6 +1654,11 @@
        tx = &a->tx;
        sztx = aufmt_sample_size(tx->src_fmt);
 
+       mtx_lock(tx->mtx);
+       uint64_t aubuf_overrun = tx->stats.aubuf_overrun;
+       uint64_t aubuf_underrun = tx->stats.aubuf_underrun;
+       mtx_unlock(tx->mtx);
+
        err  = re_hprintf(pf, "%s", "\n--- Audio stream ---\n");
 
        err |= re_hprintf(pf, " tx:   encode: %H ptime=%ums %s\n",
@@ -1665,8 +1674,8 @@
                          calc_ptime(tx->aubuf_maxsz/sztx,
                                     tx->ausrc_prm.srate,
                                     tx->ausrc_prm.ch),
-                         tx->stats.aubuf_overrun,
-                         tx->stats.aubuf_underrun);
+                         aubuf_overrun,
+                         aubuf_underrun);
        err |= re_hprintf(pf, "       source: %s,%s %s\n",
                          tx->as ? tx->as->name : "none",
                          tx->device,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/src/aureceiver.c 
new/baresip-4.12.0/src/aureceiver.c
--- old/baresip-4.11.0/src/aureceiver.c 2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/src/aureceiver.c 2026-09-30 19:40:56.000000000 +0200
@@ -34,9 +34,9 @@
 
 
 struct audio_recv {
-       uint32_t srate;               /**< Decoder sample rate               */
-       uint32_t ch;                  /**< Decoder channel number            */
        enum aufmt fmt;               /**< Decoder sample format             */
+       void *sampv;                  /**< Decoder sample buffer             */
+       size_t sampvsz;               /**< Decoder sample buffer size        */
        const struct config_audio *cfg;  /**< Audio configuration            */
        struct audec_state *dec;      /**< Audio decoder state (optional)    */
        const struct aucodec *ac;     /**< Current audio decoder             */
@@ -44,8 +44,6 @@
        mtx_t *aubuf_mtx;             /**< Mutex for aubuf allocation        */
        uint32_t ssrc;                /**< Incoming synchronization source   */
        struct list filtl;            /**< Audio filters in decoding order   */
-       void *sampv;                  /**< Sample buffer                     */
-       size_t sampvsz;               /**< Sample buffer size                */
        uint64_t t;                   /**< Last auframe push time            */
        uint32_t ptime;               /**< Packet time for receiving [us]    */
 
@@ -55,12 +53,16 @@
        uint8_t extmap_aulevel;       /**< ID Range 1-14 inclusive           */
        int pt;                       /**< Payload type of audio codec       */
 
+       uint64_t n_discard;           /**< Nbr of discarded packets          */
+       RE_ATOMIC uint64_t latency;   /**< Latency in [ms]                   */
+
+#ifndef RELEASE
        struct {
-               uint64_t n_discard;   /**< Nbr of discarded packets          */
-               RE_ATOMIC uint64_t latency;   /**< Latency in [ms]           */
+               uint64_t t;           /**< Last auframe push time            */
                int32_t jitter;       /**< Auframe push jitter [us]          */
                int32_t dmax;         /**< Max deviation [us]                */
        } stats;
+#endif
 
        mtx_t *mtx;
 
@@ -168,7 +170,6 @@
 static int aurecv_push_aubuf(struct audio_recv *ar, const struct auframe *af)
 {
        int err;
-       uint64_t bpms;
 
        if (!ar->aubuf) {
                err = aurecv_alloc_aubuf(ar, af);
@@ -180,27 +181,23 @@
        int32_t d, da;
        uint64_t t;
        t = tmr_jiffies_usec();
-       if (ar->t) {
-               d = (int32_t) (int64_t) ((t - ar->t) - ar->ptime);
+       if (ar->stats.t) {
+               d = (int32_t) (int64_t) ((t - ar->stats.t) - ar->ptime);
                da = abs(d);
                ar->stats.dmax = max(ar->stats.dmax, da);
                ar->stats.jitter += (da - ar->stats.jitter) / JITTER_EMA_COEFF;
        }
 
-       ar->t = t;
+       ar->stats.t = t;
 #endif
        err = aubuf_write_auframe(ar->aubuf, af);
        if (err)
                return err;
 
-       ar->srate = af->srate;
-       ar->ch    = af->ch;
-       ar->fmt   = af->fmt;
-
-       bpms = (uint64_t)ar->srate * ar->ch * aufmt_sample_size(ar->fmt) /
-              1000;
+       uint64_t bpms = (uint64_t)af->srate * af->ch *
+                       aufmt_sample_size(af->fmt) / 1000;
        if (bpms)
-               re_atomic_rlx_set(&ar->stats.latency,
+               re_atomic_rlx_set(&ar->latency,
                                  aubuf_cur_size(ar->aubuf) / bpms);
 
        return 0;
@@ -370,7 +367,7 @@
        ar->ts_recv.last = hdr->ts;
 
        if (discard) {
-               ++ar->stats.n_discard;
+               ++ar->n_discard;
                goto out;
        }
 
@@ -417,7 +414,7 @@
        if (!ar)
                return 0;
 
-       return re_atomic_rlx(&ar->stats.latency);
+       return re_atomic_rlx(&ar->latency);
 }
 
 
@@ -435,8 +432,6 @@
                return ENOMEM;
 
        ar->cfg = cfg;
-       ar->srate = cfg->srate_play;
-       ar->ch    = cfg->channels_play;
        ar->fmt   = cfg->dec_fmt;
        ar->play_fmt = cfg->play_fmt;
        ar->sampvsz = sampc * aufmt_sample_size(ar->fmt);
@@ -747,7 +742,6 @@
 int aurecv_debug(struct re_printf *pf, const struct audio_recv *ar)
 {
        struct mbuf *mb;
-       double bpms;
        int err;
 
        if (!ar)
@@ -760,8 +754,10 @@
        }
 
        mtx_lock(ar->mtx);
-       bpms = (double)ar->srate * ar->ch * aufmt_sample_size(ar->fmt) /
-              1000.0;
+       uint32_t srate = ar->auplay_prm.srate;
+       uint8_t ch     = ar->auplay_prm.ch;
+       int fmt        = ar->auplay_prm.fmt;
+       double bpms = (double)srate * ch * aufmt_sample_size(fmt) / 1000.0;
        err  = mbuf_printf(mb,
                           " rx:   decode: %H %s\n",
                           aucodec_print, ar->ac,
@@ -779,8 +775,7 @@
        err |= mbuf_printf(mb, "       deviation: %.2fms\n",
                           (double) ar->stats.dmax / 1000);
 #endif
-       err |= mbuf_printf(mb, "       n_discard: %llu\n",
-                          ar->stats.n_discard);
+       err |= mbuf_printf(mb, "       n_discard: %llu\n", ar->n_discard);
        if (ar->level_set) {
                err |= mbuf_printf(mb, "       level %.3f dBov\n",
                                   ar->level_last);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/src/core.h 
new/baresip-4.12.0/src/core.h
--- old/baresip-4.11.0/src/core.h       2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/src/core.h       2026-09-30 19:40:56.000000000 +0200
@@ -92,6 +92,7 @@
        bool rtcp_mux;               /**< RTCP multiplexing                  */
        bool pinhole;                /**< NAT pinhole flag                   */
        bool catchall;               /**< Catch all inbound requests         */
+       struct list custom_hdrs;     /**< Static outbound SIP headers        */
 };
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/src/jbuf.c 
new/baresip-4.12.0/src/jbuf.c
--- old/baresip-4.11.0/src/jbuf.c       2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/src/jbuf.c       2026-09-30 19:40:56.000000000 +0200
@@ -266,14 +266,15 @@
  * @param jb  The jitter buffer.
  * @param id  Identifier.
  */
-void jbuf_set_id(struct jbuf *jb, struct pl *id)
+int jbuf_set_id(struct jbuf *jb, const char *id)
 {
        if (!jb)
-               return;
+               return EINVAL;
 
        mtx_lock(jb->lock);
-       jb->id = mem_ref(id);
+       jb->id = pl_alloc_str(id);
        mtx_unlock(jb->lock);
+       return jb->id ? 0 : ENOMEM;
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/src/peerconn.c 
new/baresip-4.12.0/src/peerconn.c
--- old/baresip-4.11.0/src/peerconn.c   2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/src/peerconn.c   2026-09-30 19:40:56.000000000 +0200
@@ -347,7 +347,8 @@
  */
 int peerconnection_add_video_track(struct peer_connection *pc,
                                   const struct config *cfg,
-                                  struct list *vidcodecl, enum sdp_dir dir)
+                                  struct list *vidcodecl,
+                                  struct list *vidfiltl, enum sdp_dir dir)
 {
        struct media_track *media;
        bool offerer;
@@ -370,7 +371,7 @@
 
        err = video_alloc(&media->u.vid, &pc->streaml, &pc->stream_prm, cfg,
                          NULL, pc->sdp, pc->mnat, pc->mnats, pc->menc,
-                         pc->mencs, NULL, vidcodecl, NULL, offerer,
+                         pc->mencs, NULL, vidcodecl, vidfiltl, offerer,
                          video_error_handler, media);
        if (err) {
                warning("peerconnection: video alloc failed (%m)\n", err);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/src/play.c 
new/baresip-4.12.0/src/play.c
--- old/baresip-4.11.0/src/play.c       2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/src/play.c       2026-09-30 19:40:56.000000000 +0200
@@ -366,13 +366,12 @@
 static void ausrc_error_handler(int err, const char *str, void *arg)
 {
        struct play *play = arg;
+       (void)err;
        (void)str;
 
-       if (err == 0) {
-               mtx_lock(&play->lock);
-               play->ausrc_st = mem_deref(play->ausrc_st);
-               mtx_unlock(&play->lock);
-       }
+       mtx_lock(&play->lock);
+       play->ausrc_st = mem_deref(play->ausrc_st);
+       mtx_unlock(&play->lock);
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/src/rtprecv.c 
new/baresip-4.12.0/src/rtprecv.c
--- old/baresip-4.11.0/src/rtprecv.c    2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/src/rtprecv.c    2026-09-30 19:40:56.000000000 +0200
@@ -32,6 +32,7 @@
        bool pseq_set;                 /**< True if sequence number is set   */
        bool rtp_estab;                /**< True if RTP stream established   */
        RE_ATOMIC bool run;            /**< True if RX thread is running     */
+       RE_ATOMIC bool stop;           /**< True if RX thread should stop    */
        bool start_rtcp;               /**< Start RTCP flag                  */
        char *cname;                   /**< Canonical Name for RTCP send     */
        struct sa rtcp_peer;           /**< RTCP address of Peer             */
@@ -173,35 +174,35 @@
 {
        struct rtp_receiver *rx = arg;
 
-       if (re_atomic_rlx(&rx->run)) {
-               mtx_lock(rx->mtx);
-               bool pinhole    = rx->pinhole;
+       if (re_atomic_rlx(&rx->stop)) {
+               tmr_cancel(&rx->tmr_decode);
+               udp_thread_detach(rtp_sock(rx->rtp));
+               udp_thread_detach(rtcp_sock(rx->rtp));
+               re_cancel();
+               return;
+       }
+
+       mtx_lock(rx->mtx);
+       bool pinhole    = rx->pinhole;
+       mtx_unlock(rx->mtx);
+       tmr_start(&rx->tmr, 10, rtprecv_periodic, rx);
+       mtx_lock(rx->mtx);
+       if (rx->start_rtcp) {
+               int err = 0;
+               rx->start_rtcp = false;
+               rtcp_start(rx->rtp, rx->cname, &rx->rtcp_peer);
                mtx_unlock(rx->mtx);
-               tmr_start(&rx->tmr, 10, rtprecv_periodic, rx);
-               mtx_lock(rx->mtx);
-               if (rx->start_rtcp) {
-                       int err = 0;
-                       rx->start_rtcp = false;
-                       rtcp_start(rx->rtp, rx->cname, &rx->rtcp_peer);
-                       mtx_unlock(rx->mtx);
-                       if (pinhole) {
-                               err = rtcp_send_app(rx->rtp, "PING",
-                                                   (void *)"PONG", 4);
-                       }
-                       if (err) {
-                               warning("rtprecv: rtcp_send_app failed (%m)\n",
-                                       err);
-                       }
+               if (pinhole) {
+                       err = rtcp_send_app(rx->rtp, "PING",
+                                           (void *)"PONG", 4);
                }
-               else {
-                       mtx_unlock(rx->mtx);
+               if (err) {
+                       warning("rtprecv: rtcp_send_app failed (%m)\n",
+                               err);
                }
        }
        else {
-               tmr_cancel(&rx->tmr_decode);
-               udp_thread_detach(rtp_sock(rx->rtp));
-               udp_thread_detach(rtcp_sock(rx->rtp));
-               re_cancel();
+               mtx_unlock(rx->mtx);
        }
 }
 
@@ -231,6 +232,7 @@
                return err;
        }
 
+       rtprecv_enable(rx, true);
        err = re_main(NULL);
 
        tmr_cancel(&rx->tmr);
@@ -439,12 +441,13 @@
        metric_add_packet(rx->metric, mbuf_get_left(mb));
 
        if (!rx->rtp_estab) {
+               rx->rtp_estab = true;
                if (rx->rtpestabh) {
                        debug("rtprecv: incoming rtp for '%s' established, "
                              "receiving from %J\n", rx->name, src);
-                       rx->rtp_estab = true;
                        pass_rtpestab_work(rx);
                }
+
                tmr_start(&rx->tmr_decode, 0, decode_tmr, rx);
        }
 
@@ -724,8 +727,9 @@
 
        if (re_atomic_rlx(&rx->run)) {
                rtprecv_enable(rx, false);
-               re_atomic_rlx_set(&rx->run, false);
+               re_atomic_rlx_set(&rx->stop, true);
                thrd_join(rx->thr, NULL);
+               re_atomic_rlx_set(&rx->run, false);
                re_thread_async_main_cancel((intptr_t)rx);
        }
        else {
@@ -802,13 +806,10 @@
                        goto out;
        }
 
-       struct pl *id = pl_alloc_str(name);
-       if (!id)
+       err = jbuf_set_id(rx->jbuf, name);
+       if (err)
                goto out;
 
-       jbuf_set_id(rx->jbuf, id);
-       mem_deref(id);
-
        rx->metric = metric_alloc();
        if (!rx->metric)
                err = ENOMEM;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/src/stream.c 
new/baresip-4.12.0/src/stream.c
--- old/baresip-4.11.0/src/stream.c     2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/src/stream.c     2026-09-30 19:40:56.000000000 +0200
@@ -257,7 +257,6 @@
                return ENOTSUP;
 
        debug("stream: enable %s RTP receiver\n", media_name(strm->type));
-       rtprecv_enable(strm->rx, true);
 
        if (strm->rtp && strm->cfg.rxmode == RECEIVE_MODE_THREAD &&
            strm->type == MEDIA_AUDIO && !rtprecv_running(strm->rx)) {
@@ -270,9 +269,11 @@
                        strm->rxm.use_rxthread = true;
                        tmr_start(&strm->rxm.tmr_rec, 1, stream_start_receiver,
                                  strm);
+                       return 0;
                }
        }
 
+       rtprecv_enable(strm->rx, true);
        return 0;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/src/ua.c new/baresip-4.12.0/src/ua.c
--- old/baresip-4.11.0/src/ua.c 2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/src/ua.c 2026-09-30 19:40:56.000000000 +0200
@@ -27,7 +27,6 @@
        char *pub_gruu;              /**< SIP Public GRUU                    */
        enum presence_status pstat;  /**< Presence Status                    */
        struct list hdr_filter;      /**< Filter for incoming headers        */
-       struct list custom_hdrs;     /**< List of outgoing headers           */
        char *ansval;                /**< SIP auto answer value              */
        struct sa dst;               /**< Current destination address        */
 };
@@ -65,7 +64,6 @@
                sip_close(uag_sip(), false);
        }
 
-       list_flush(&ua->custom_hdrs);
        list_flush(&ua->hdr_filter);
 }
 
@@ -222,8 +220,8 @@
        for (le = ua->regl.head, i=0; le; le = le->next, i++) {
                struct reg *reg = le->data;
 
-               if (!list_isempty(&ua->custom_hdrs))
-                       reg_set_custom_hdrs(reg, &ua->custom_hdrs);
+               if (!list_isempty(&ua->acc->custom_hdrs))
+                       reg_set_custom_hdrs(reg, &ua->acc->custom_hdrs);
 
                err = reg_register(reg, reg_uri, params,
                                   fallback ? 0 : acc->regint,
@@ -958,8 +956,8 @@
        if (err)
                return err;
 
-       if (!list_isempty(&ua->custom_hdrs))
-               call_set_custom_hdrs(*callp, &ua->custom_hdrs);
+       if (!list_isempty(&ua->acc->custom_hdrs))
+               call_set_custom_hdrs(*callp, &ua->acc->custom_hdrs);
 
        call_set_handlers(*callp, NULL, call_dtmf_handler, ua);
 
@@ -2128,7 +2126,7 @@
        if (err)
                return err;
 
-       err = custom_hdrs_add(&ua->custom_hdrs, buf, "%r", value);
+       err = custom_hdrs_add(&ua->acc->custom_hdrs, buf, "%r", value);
        mem_deref(buf);
        if (err)
                return err;
@@ -2152,7 +2150,7 @@
        if (!ua)
                return EINVAL;
 
-       le = list_head(&ua->custom_hdrs);
+       le = list_head(&ua->acc->custom_hdrs);
        while (le) {
                struct sip_hdr *h = le->data;
                le = le->next;
@@ -2183,7 +2181,7 @@
        if (!ua)
                return EINVAL;
 
-       list_flush(&ua->custom_hdrs);
+       list_flush(&ua->acc->custom_hdrs);
 
        LIST_FOREACH(custom_headers, le) {
                const struct sip_hdr *hdr = le->data;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/test/account.c 
new/baresip-4.12.0/test/account.c
--- old/baresip-4.11.0/test/account.c   2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/test/account.c   2026-09-30 19:40:56.000000000 +0200
@@ -58,6 +58,7 @@
        ";video_codecs=h266"
        ";video_display=sdl,default"
        ";video_source=null,null"
+       ";x_headers=X-Foo:bar,X-Baz:qux"
        ;
 
 
@@ -136,6 +137,8 @@
        err = verify_account(acc);
        TEST_ERR(err);
 
+       ASSERT_EQ(2, list_count(account_custom_hdrs(acc)));
+
        acc = mem_deref(acc);
 
        err = account_alloc(&acc, "sip:[email protected]");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/test/call.c 
new/baresip-4.12.0/test/call.c
--- old/baresip-4.11.0/test/call.c      2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/test/call.c      2026-09-30 19:40:56.000000000 +0200
@@ -1661,6 +1661,62 @@
 }
 
 
+int test_call_account_custom_headers(void)
+{
+       struct fixture fix, *f = &fix;
+       int err = 0;
+       bool headers_matched = true;
+
+       fixture_init_prm(f, ";x_headers=X-CALL_ID:7,X-HEADER_NAME:VALUE");
+
+       ua_add_xhdr_filter(f->b.ua, "X-CALL_ID");
+       ua_add_xhdr_filter(f->b.ua, "X-HEADER_NAME");
+
+       f->behaviour = BEHAVIOUR_GET_HDRS;
+
+       err = ua_connect(f->a.ua, 0, NULL, f->buri, VIDMODE_OFF);
+       TEST_ERR(err);
+
+       err = re_main_timeout(5000);
+
+       if (!list_isempty(f->hdrs)) {
+               struct le *le;
+               for (le = list_head(f->hdrs); le; le = le->next) {
+                       struct sip_hdr *hdr = le->data;
+                       if (pl_strcasecmp(&hdr->name, "X-CALL_ID") == 0) {
+                               if (pl_strcasecmp(&hdr->val, "7") != 0)
+                                       headers_matched = false;
+                       }
+                       if (pl_strcasecmp(&hdr->name, "X-HEADER_NAME") == 0) {
+                               if (pl_strcasecmp(&hdr->val, "VALUE") != 0)
+                                       headers_matched = false;
+                       }
+               }
+       }
+       else {
+               headers_matched = false;
+       }
+
+       ASSERT_TRUE(headers_matched);
+
+       TEST_ERR(err);
+       TEST_ERR(fix.err);
+
+       ASSERT_EQ(0, fix.a.n_incoming);
+       ASSERT_EQ(1, fix.a.n_established);
+       ASSERT_EQ(0, fix.a.n_closed);
+
+       ASSERT_EQ(1, fix.b.n_incoming);
+       ASSERT_EQ(1, fix.b.n_established);
+       ASSERT_EQ(0, fix.b.n_closed);
+
+ out:
+       fixture_close(f);
+
+       return err;
+}
+
+
 int test_call_tcp(void)
 {
        struct fixture fix, *f = &fix;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/test/main.c 
new/baresip-4.12.0/test/main.c
--- old/baresip-4.11.0/test/main.c      2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/test/main.c      2026-09-30 19:40:56.000000000 +0200
@@ -30,6 +30,7 @@
        TEST(test_call_answer_hangup_b),
        TEST(test_call_aulevel),
        TEST(test_call_custom_headers),
+       TEST(test_call_account_custom_headers),
        TEST(test_call_dtmf),
        TEST(test_call_format_float),
        TEST(test_call_max),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/test/peerconn.c 
new/baresip-4.12.0/test/peerconn.c
--- old/baresip-4.11.0/test/peerconn.c  2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/test/peerconn.c  2026-09-30 19:40:56.000000000 +0200
@@ -296,6 +296,7 @@
        if (use_video) {
                err = peerconnection_add_video_track(ag->pc, conf_config(),
                                                     baresip_vidcodecl(),
+                                                    baresip_vidfiltl(),
                                                     SDP_SENDRECV);
                TEST_ERR(err);
        }
@@ -360,13 +361,18 @@
 }
 
 
-static int test_peerconn_param(bool use_audio, bool use_aufilt, bool use_video)
+static int test_peerconn_param(bool use_audio, bool use_aufilt,
+                              bool use_video, bool use_vidfilt)
 {
        const char *aufilters[] = {
                "auconv",
                "auresamp",
                "mixausrc",
        };
+       const char *vidfilters[] = {
+               "selfview",
+               "vidinfo",
+       };
        struct fixture fix = {0};
        struct auplay *auplay = NULL;
        struct vidisp *vidisp = NULL;
@@ -403,6 +409,15 @@
 
                err = module_load(".", "fakevideo");
                TEST_ERR(err);
+
+               if (use_vidfilt) {
+                       for (size_t i=0; i<RE_ARRAY_SIZE(vidfilters); i++) {
+                               const char *name = vidfilters[i];
+
+                               err = module_load(".", name);
+                               TEST_ERR(err);
+                       }
+               }
        }
 
        const struct mnat *mnat = mnat_find(baresip_mnatl(), "ice");
@@ -465,6 +480,14 @@
                mem_deref(auplay);
        }
        if (use_video) {
+               if (use_vidfilt) {
+                       for (size_t i=0; i<RE_ARRAY_SIZE(vidfilters); i++) {
+                               const char *name = vidfilters[i];
+
+                               module_unload(name);
+                       }
+               }
+
                module_unload("fakevideo");
                mock_vidcodec_unregister();
                mem_deref(vidisp);
@@ -506,14 +529,16 @@
        err = module_load(".", "ice");
        TEST_ERR(err);
 
-       err = test_peerconn_param(1, 0, 0);
+       err = test_peerconn_param(1, 0, 0, 0);
        TEST_ERR(err);
-       err = test_peerconn_param(0, 0, 1);
+       err = test_peerconn_param(0, 0, 1, 0);
        TEST_ERR(err);
-       err = test_peerconn_param(1, 0, 1);
+       err = test_peerconn_param(1, 0, 1, 0);
        TEST_ERR(err);
 
-       err = test_peerconn_param(1, 1, 0);
+       err = test_peerconn_param(1, 1, 0, 0);
+       TEST_ERR(err);
+       err = test_peerconn_param(0, 0, 1, 1);
        TEST_ERR(err);
 
  out:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/test/test.h 
new/baresip-4.12.0/test/test.h
--- old/baresip-4.11.0/test/test.h      2026-08-24 13:09:33.000000000 +0200
+++ new/baresip-4.12.0/test/test.h      2026-09-30 19:40:56.000000000 +0200
@@ -203,6 +203,7 @@
 int test_call_answer_hangup_b(void);
 int test_call_aulevel(void);
 int test_call_custom_headers(void);
+int test_call_account_custom_headers(void);
 int test_call_dtmf(void);
 int test_call_format_float(void);
 int test_call_max(void);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/baresip-4.11.0/webrtc/src/sess.c 
new/baresip-4.12.0/webrtc/src/sess.c
--- old/baresip-4.11.0/webrtc/src/sess.c        2026-08-24 13:09:33.000000000 
+0200
+++ new/baresip-4.12.0/webrtc/src/sess.c        2026-09-30 19:40:56.000000000 
+0200
@@ -160,7 +160,8 @@
        }
 
        err = peerconnection_add_video_track(
-               sess->pc, config, baresip_vidcodecl(), SDP_SENDRECV);
+               sess->pc, config, baresip_vidcodecl(),
+               baresip_vidfiltl(), SDP_SENDRECV);
        if (err) {
                warning("demo: add_video failed (%m)\n", err);
                return err;

Reply via email to