Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package rem for openSUSE:Factory checked in at 2022-09-07 11:05:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rem (Old) and /work/SRC/openSUSE:Factory/.rem.new.2083 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rem" Wed Sep 7 11:05:58 2022 rev:4 rq:1001458 version:2.6.0 Changes: -------- --- /work/SRC/openSUSE:Factory/rem/rem.changes 2022-07-02 15:34:21.115000628 +0200 +++ /work/SRC/openSUSE:Factory/.rem.new.2083/rem.changes 2022-09-07 11:06:07.228419313 +0200 @@ -1,0 +2,6 @@ +Thu Aug 25 22:39:08 UTC 2022 - Jan Engelhardt <jeng...@inai.de> + +- Update to release 2.6.0 + * aubuf: prevent faulty timestamps + +------------------------------------------------------------------- Old: ---- rem-2.4.0.tar.gz New: ---- rem-2.6.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rem.spec ++++++ --- /var/tmp/diff_new_pack.3sus3y/_old 2022-09-07 11:06:07.784420726 +0200 +++ /var/tmp/diff_new_pack.3sus3y/_new 2022-09-07 11:06:07.788420736 +0200 @@ -19,13 +19,13 @@ %global sover 3 %global libname lib%{name}%{sover} Name: rem -Version: 2.4.0 +Version: 2.6.0 Release: 0 Summary: Audio and Video processing media library License: BSD-3-Clause Group: Development/Libraries/C and C++ URL: https://github.com/baresip/rem -Source: %{URL}/archive/v%{version}/%{name}-%{version}.tar.gz +Source: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz BuildRequires: pkgconfig BuildRequires: pkgconfig(libre) >= 2.4.0 @@ -52,7 +52,7 @@ %package devel Summary: Librem development files Group: Development/Libraries/C and C++ -Requires: %{libname} = %{version} +Requires: %{libname} = %{version}-%{release} %description devel Librem is a generic library for real-time audio ++++++ rem-2.4.0.tar.gz -> rem-2.6.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/.github/workflows/build.yml new/rem-2.6.0/.github/workflows/build.yml --- old/rem-2.4.0/.github/workflows/build.yml 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/.github/workflows/build.yml 2022-07-29 16:23:47.000000000 +0200 @@ -19,20 +19,25 @@ steps: - uses: actions/checkout@v2 - - uses: sreimers/pr-dependency-action@v0.3 + - uses: sreimers/pr-dependency-action@v0.5 with: name: re repo: https://github.com/baresip/re secret: ${{ secrets.GITHUB_TOKEN }} working-directory: '../.' - - uses: sreimers/pr-dependency-action@v0.3 + - uses: sreimers/pr-dependency-action@v0.5 with: name: retest repo: https://github.com/baresip/retest.git secret: ${{ secrets.GITHUB_TOKEN }} working-directory: '../.' + - name: openssl path macos + if: ${{ runner.os == 'macOS' }} + run: | + echo "OPENSSL_ROOT_DIR=/usr/local/opt/openssl" >> $GITHUB_ENV + - name: retest run: | cd .. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/.github/workflows/mingw.yml new/rem-2.6.0/.github/workflows/mingw.yml --- old/rem-2.4.0/.github/workflows/mingw.yml 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/.github/workflows/mingw.yml 2022-07-29 16:23:47.000000000 +0200 @@ -13,13 +13,13 @@ - uses: actions/checkout@v2 # needed for pr checkout - - uses: sreimers/pr-dependency-action@v0.3 + - uses: sreimers/pr-dependency-action@v0.5 with: name: re repo: https://github.com/baresip/re secret: ${{ secrets.GITHUB_TOKEN }} - - uses: sreimers/pr-dependency-action@v0.3 + - uses: sreimers/pr-dependency-action@v0.5 with: name: retest repo: https://github.com/baresip/retest @@ -68,7 +68,7 @@ with: path: baresip - - uses: sreimers/pr-dependency-action@v0.3 + - uses: sreimers/pr-dependency-action@v0.5 with: name: retest repo: https://github.com/baresip/retest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/CHANGELOG.md new/rem-2.6.0/CHANGELOG.md --- old/rem-2.4.0/CHANGELOG.md 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/CHANGELOG.md 2022-07-29 16:23:47.000000000 +0200 @@ -9,6 +9,19 @@ --- +## [v2.5.0] - 2022-07-01 + +## What's Changed +* ci/build: fix macOS openssl path by @sreimers in https://github.com/baresip/rem/pull/59 +* vidmix: use C11 mutex by @alfredh in https://github.com/baresip/rem/pull/58 +* aubuf: fix possible data race warning by @cspiel1 in https://github.com/baresip/rem/pull/61 +* aubuf: C11 mutex by @alfredh in https://github.com/baresip/rem/pull/62 +* ajb: C11 mutex by @alfredh in https://github.com/baresip/rem/pull/63 +* aubuf: correct ajb reset on frame drop and on underruns by @cspiel1 in https://github.com/baresip/rem/pull/64 +* aubuf: better support for different put/get ptime by @cspiel1 in https://github.com/baresip/rem/pull/65 + +--- + ## [v2.4.0] - 2022-06-01 ### What's Changed diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/CMakeLists.txt new/rem-2.6.0/CMakeLists.txt --- old/rem-2.4.0/CMakeLists.txt 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/CMakeLists.txt 2022-07-29 16:23:47.000000000 +0200 @@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.7) -project(rem VERSION 2.4.0 LANGUAGES C) +project(rem VERSION 2.6.0 LANGUAGES C) set(PROJECT_SOVERSION 3) # bump if ABI breaks @@ -61,7 +61,7 @@ link_directories(/usr/local/lib) add_definitions(-DVERSION="${PROJECT_VERSION}") -add_library(${PROJECT_NAME} +set(SRCS src/aac/aac.c src/au/fmt.c src/au/util.c @@ -87,6 +87,37 @@ src/vidmix/vidmix.c ) +set(HEADERS + include/rem_aac.h + include/rem_aubuf.h + include/rem_auconv.h + include/rem_audio.h + include/rem_aufile.h + include/rem_auframe.h + include/rem_au.h + include/rem_aulevel.h + include/rem_aumix.h + include/rem_auresamp.h + include/rem_autone.h + include/rem_avc.h + include/rem_dsp.h + include/rem_dtmf.h + include/rem_fir.h + include/rem_flv.h + include/rem_g711.h + include/rem_goertzel.h + include/rem.h + include/rem_vidconv.h + include/rem_video.h + include/rem_vid.h + include/rem_vidmix.h +) + +add_library(${PROJECT_NAME} + ${SRCS} + ${HEADERS} +) + ############################################################################## # # Main target object @@ -95,3 +126,6 @@ target_link_libraries(${PROJECT_NAME} re -lpthread -lm) set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${PROJECT_SOVERSION}) + +set_target_properties(rem PROPERTIES PUBLIC_HEADER "${HEADERS}") +install(TARGETS rem LIBRARY) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/Makefile new/rem-2.6.0/Makefile --- old/rem-2.4.0/Makefile 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/Makefile 2022-07-29 16:23:47.000000000 +0200 @@ -6,7 +6,7 @@ # Main version number VER_MAJOR := 2 -VER_MINOR := 4 +VER_MINOR := 6 VER_PATCH := 0 # Development version, comment out on a release @@ -26,7 +26,7 @@ VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_PATCH)-$(VER_PRE) endif OPT_SPEED := 1 -LIBRE_MIN := 2.4.0 +LIBRE_MIN := 2.6.0 ifndef LIBRE_MK LIBRE_MK := $(shell [ -f ../re/mk/re.mk ] && \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/debian/changelog new/rem-2.6.0/debian/changelog --- old/rem-2.4.0/debian/changelog 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/debian/changelog 2022-07-29 16:23:47.000000000 +0200 @@ -1,3 +1,9 @@ +librem (2.5.0) unstable; urgency=medium + + * version 2.5.0 + + -- Christian Spielberger <c.spielber...@commend.com> Fri, 1 Jul 2022 08:00:00 +0200 + librem (2.4.0) unstable; urgency=medium * version 2.4.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/docs/aubuf/ajb.plot new/rem-2.6.0/docs/aubuf/ajb.plot --- old/rem-2.4.0/docs/aubuf/ajb.plot 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/docs/aubuf/ajb.plot 2022-07-29 16:23:47.000000000 +0200 @@ -57,7 +57,7 @@ # Choose your preferred gnuplot terminal or use e.g. evince to view the # ajb.eps! -#set terminal x11 +#set terminal qt persist set terminal postscript eps size 15,10 enhanced color set output 'ajb.eps' #set terminal png size 1280,480 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/docs/aubuf/config new/rem-2.6.0/docs/aubuf/config --- old/rem-2.4.0/docs/aubuf/config 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/docs/aubuf/config 2022-07-29 16:23:47.000000000 +0200 @@ -1,14 +1,17 @@ #audio_path /usr/local/share/baresip -audio_player pulse, -audio_source pulse, -audio_alert pulse, +audio_player pulse_async, +audio_source pulse_async, +audio_alert pulse_async, audio_level no -audio_buffer 20-160 +audio_buffer 30-250 audio_buffer_mode adaptive audio_silence 0.0 jitter_buffer_type adaptive -jitter_buffer_delay 0-5 +jitter_buffer_delay 0-25 + +statmode_default off +rtp_stats no module_path /usr/local/lib/baresip/modules diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/docs/aubuf/generate_plots.sh new/rem-2.6.0/docs/aubuf/generate_plots.sh --- old/rem-2.4.0/docs/aubuf/generate_plots.sh 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/docs/aubuf/generate_plots.sh 2022-07-29 16:23:47.000000000 +0200 @@ -16,7 +16,7 @@ function enable_jitter() { echo "ENABLE JITTER ..." - sudo tc qdisc add dev ifb1 root netem delay 100ms 50ms + sudo tc qdisc add dev ifb1 root netem delay 0ms 150ms } @@ -47,11 +47,11 @@ for ptime in 20 10 5 15 30 40; do sed -e "s/ptime=[0-9]*/ptime=$ptime/" -i accounts - for buf in $ptime $(( 2*ptime )) $(( 3*ptime )) $(( 4*ptime )) $(( 6*ptime )); do + for buf in $(( ptime + ptime/2 )) $(( ptime )) $(( 2*ptime )) $(( 4*ptime )) $(( 6*ptime )); do echo "########### ptime $ptime buffer $buf ###############" - sed -e "s/audio_buffer\s*[0-9]*\-.*/audio_buffer $buf-160/" -i config - baresip -f . > /tmp/b.log 2>&1 & + sed -e "s/audio_buffer\s*[0-9]*\-.*/audio_buffer $buf-250/" -i config + baresip -v -f . > /tmp/b.log 2>&1 & sleep 1 echo "/dial $target" | nc -N localhost 5555 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/include/rem_auframe.h new/rem-2.6.0/include/rem_auframe.h --- old/rem-2.4.0/include/rem_auframe.h 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/include/rem_auframe.h 2022-07-29 16:23:47.000000000 +0200 @@ -2,6 +2,8 @@ * Audio frame */ +#define AUDIO_TIMEBASE 1000000U + /** * Defines a frame of audio samples */ @@ -42,3 +44,4 @@ size_t auframe_size(const struct auframe *af); void auframe_mute(struct auframe *af); double auframe_level(struct auframe *af); +size_t auframe_bytes_to_timestamp(const struct auframe *af, size_t n); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/include/rem_aumix.h new/rem-2.6.0/include/rem_aumix.h --- old/rem-2.4.0/include/rem_aumix.h 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/include/rem_aumix.h 2022-07-29 16:23:47.000000000 +0200 @@ -10,9 +10,9 @@ /** * Audio mixer frame handler * - * @param buf Buffer with audio samples - * @param sz Number of bytes - * @param arg Handler argument + * @param sampv Buffer with audio samples + * @param sampc Number of samples + * @param arg Handler argument */ typedef void (aumix_frame_h)(const int16_t *sampv, size_t sampc, void *arg); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/mk/Doxyfile new/rem-2.6.0/mk/Doxyfile --- old/rem-2.4.0/mk/Doxyfile 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/mk/Doxyfile 2022-07-29 16:23:47.000000000 +0200 @@ -112,7 +112,7 @@ # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 5 +#COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output @@ -141,7 +141,7 @@ LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO -PAPER_TYPE = a4wide +#PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = NO @@ -200,11 +200,11 @@ GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl +#PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES +#CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES HAVE_DOT = YES CLASS_GRAPH = YES diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/src/aubuf/ajb.c new/rem-2.6.0/src/aubuf/ajb.c --- old/rem-2.4.0/src/aubuf/ajb.c 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/src/aubuf/ajb.c 2022-07-29 16:23:47.000000000 +0200 @@ -32,10 +32,11 @@ /** Adaptive jitter buffer statistics */ struct ajb { int32_t jitter; /**< Jitter in [us] */ - struct lock *lock; + mtx_t *lock; - uint64_t ts0; /**< previous timestamp */ - uint64_t tr0; /**< previous time of arrival */ + uint64_t ts; /**< previous timestamp */ + uint64_t ts0; /**< reference timestamp */ + uint64_t tr0; /**< reference time of arrival */ uint64_t tr00; /**< arrival of first packet */ #if DEBUG_LEVEL >= 6 struct { @@ -51,10 +52,9 @@ enum ajb_state as; /**< computed jitter buffer state */ - uint32_t ptime; /**< Packet time [us] */ int32_t avbuftime; /**< average buffered time [us] */ bool started; /**< Started flag */ - uint32_t bufmin; /**< Minimum buffer time [us] */ + size_t wish_sz; /**< Wish size of buffer [Bytes] */ struct auframe af; /**< Audio frame of last ajb_get() */ uint32_t dropped; /**< Dropped audio frames counter */ double silence; /**< Silence audio level */ @@ -131,9 +131,11 @@ /** * Initializes the adaptive jitter buffer statistics * - * @param ajb Adaptive jitter buffer statistics + * @param silence Silence audio level + * + * @return ajb Adaptive jitter buffer statistics */ -struct ajb *ajb_alloc(double silence) +struct ajb *ajb_alloc(double silence, size_t wish_sz) { struct ajb *ajb; int err; @@ -142,7 +144,7 @@ if (!ajb) return NULL; - err = lock_alloc(&ajb->lock); + err = mutex_alloc(&ajb->lock); if (err) goto out; @@ -150,6 +152,7 @@ ajb->tr0 = 0; ajb->as = AJB_GOOD; ajb->silence = silence; + ajb->wish_sz = wish_sz; #if DEBUG_LEVEL >= 6 (void)re_trace_init("ajb.json"); #endif @@ -167,14 +170,15 @@ if (!ajb) return; - lock_write_get(ajb->lock); + mtx_lock(ajb->lock); + ajb->ts = 0; ajb->ts0 = 0; ajb->tr0 = 0; /* We start with wish size. */ ajb->started = false; ajb->as = AJB_GOOD; - lock_rel(ajb->lock); + mtx_unlock(ajb->lock); } @@ -189,30 +193,31 @@ { uint64_t tr; /**< Real time in [us] */ uint32_t buftime, bufmax, bufmin; /**< Buffer time in [us] */ + uint32_t bufwish; /**< Buffer wish time in [us] */ int32_t d; /**< Time shift in [us] */ int32_t da; /**< Absolut time shift in [us] */ int32_t s; /**< EMA coefficient */ - int64_t ts; /**< Time stamp */ - size_t sz; - + uint64_t ts; /**< Time stamp */ + uint64_t ds; /**< Time stamp duration */ + uint32_t ptime; /**< Packet time [us] */ + size_t szdiv; if (!ajb || !af || !af->srate) return; - lock_write_get(ajb->lock); - sz = aufmt_sample_size(af->fmt); - ts = (int64_t) af->timestamp; + mtx_lock(ajb->lock); + ts = af->timestamp; tr = tmr_jiffies_usec(); if (!ajb->ts0) goto out; - d = (int32_t) ( ((int64_t) tr - (int64_t) ajb->tr0) - - (ts - (int64_t) ajb->ts0) ); - + ds = ts - ajb->ts0; + d = (int32_t) (int64_t) ( (tr - ajb->tr0) - ds ); da = abs(d); - buftime = (uint32_t) (cur_sz * 1000 / - (af->srate * af->ch * sz / 1000)); + szdiv = af->srate * af->ch * aufmt_sample_size(af->fmt) / 1000; + buftime = (uint32_t) (cur_sz * 1000 / szdiv); + bufwish = (uint32_t) (ajb->wish_sz * 1000 / szdiv); if (ajb->started) { ajb->avbuftime += ((int32_t) buftime - ajb->avbuftime) / BUFTIME_EMA_COEFF; @@ -228,9 +233,6 @@ ajb->started = true; } - if (!ajb->ptime) - goto out; - s = da > ajb->jitter ? JITTER_UP_SPEED : 1; ajb->jitter += (da - ajb->jitter) * s / JITTER_EMA_COEFF; @@ -240,9 +242,16 @@ bufmin = (uint32_t) ajb->jitter * BUFTIME_LO / 100; bufmax = (uint32_t) ajb->jitter * BUFTIME_HI / 100; - bufmin = MAX(bufmin, ajb->ptime * 2 / 3); - bufmax = MAX(bufmax, bufmin + 7 * ajb->ptime / 6); - ajb->bufmin = bufmin; + ptime = (uint32_t) (af->sampc * AUDIO_TIMEBASE / (af->srate * af->ch)); + bufmin = MAX(bufmin, ptime * 2 / 3); + if (bufwish >= ptime) + bufmin = MAX(bufmin, bufwish - ptime / 3); + + bufmax = MAX(bufmax, bufmin + 7 * ptime / 6); + + /* reset time base if a frame is missing */ + if (ts - ajb->ts > ptime) + ajb->ts0 = 0; if ((uint32_t) ajb->avbuftime < bufmin) ajb->as = AJB_LOW; @@ -259,42 +268,41 @@ plot_ajb(ajb, tr / 1000); #endif out: - ajb->ts0 = ts; - ajb->tr0 = tr; - lock_rel(ajb->lock); + ajb->ts = ts; + if (!ajb->ts0) { + ajb->ts0 = ts; + ajb->tr0 = tr; + } + mtx_unlock(ajb->lock); } -/** - * This function is for reporting that the given audio frame is not appended. - * Instead the timestamp is stored in `ts0` to avoid a jump of the computed - * jitter value. - * @param ajb Adaptive jitter buffer statistics - * @param af Audio frame - */ -void ajb_drop(struct ajb *ajb, const struct auframe *af) +void ajb_set_ts0(struct ajb *ajb, uint64_t timestamp) { - if (!ajb || !af) + if (!ajb) return; - lock_write_get(ajb->lock); - ajb->ts0 = af->timestamp; - lock_rel(ajb->lock); + mtx_lock(ajb->lock); + ajb->ts = timestamp; + ajb->ts0 = timestamp; + ajb->tr0 = tmr_jiffies_usec(); + mtx_unlock(ajb->lock); } enum ajb_state ajb_get(struct ajb *ajb, struct auframe *af) { enum ajb_state as = AJB_GOOD; + uint32_t ptime; /**< Packet time [us] */ if (!ajb || !af || !af->srate || !af->sampc) return AJB_GOOD; - lock_write_get(ajb->lock); + mtx_lock(ajb->lock); ajb->af = *af; /* ptime in [us] */ - ajb->ptime = (uint32_t) (af->sampc * 1000 * 1000 / af->srate); + ptime = (uint32_t) (af->sampc * AUDIO_TIMEBASE / (af->srate * af->ch)); if (!ajb->avbuftime) goto out; @@ -305,7 +313,7 @@ as = ajb->as; if (as == AJB_HIGH) { /* early adjustment of avbuftime */ - ajb->avbuftime -= ajb->ptime; + ajb->avbuftime -= ptime; ajb->as = AJB_GOOD; #if DEBUG_LEVEL >= 6 ajb->plot.as = AJB_HIGH; @@ -315,7 +323,7 @@ } else if (as == AJB_LOW) { /* early adjustment */ - ajb->avbuftime += ajb->ptime; + ajb->avbuftime += ptime; ajb->as = AJB_GOOD; #if DEBUG_LEVEL >= 6 ajb->plot.as = AJB_LOW; @@ -325,7 +333,7 @@ } out: - lock_rel(ajb->lock); + mtx_unlock(ajb->lock); return as; } @@ -337,9 +345,9 @@ if (!ajb) return 0; - lock_write_get(ajb->lock); + mtx_lock(ajb->lock); jitter = ajb->jitter; - lock_rel(ajb->lock); + mtx_unlock(ajb->lock); re_printf(" ajb jitter: %d, ajb avbuftime: %d\n", jitter / 1000, ajb->avbuftime); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/src/aubuf/ajb.h new/rem-2.6.0/src/aubuf/ajb.h --- old/rem-2.4.0/src/aubuf/ajb.h 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/src/aubuf/ajb.h 2022-07-29 16:23:47.000000000 +0200 @@ -4,7 +4,6 @@ * Copyright (C) 2022 Commend.com - c.spielber...@commend.com */ - enum ajb_state { AJB_GOOD = 0, AJB_LOW, @@ -13,10 +12,10 @@ struct ajb; -struct ajb *ajb_alloc(double silence); +struct ajb *ajb_alloc(double silence, size_t wish_sz); void ajb_reset(struct ajb *ajb); void ajb_calc(struct ajb *ajb, const struct auframe *af, size_t sampc); enum ajb_state ajb_get(struct ajb *ajb, struct auframe *af); int32_t ajb_debug(const struct ajb *ajb); void plot_underrun(struct ajb *ajb); -void ajb_drop(struct ajb *ajb, const struct auframe *af); +void ajb_set_ts0(struct ajb *ajb, uint64_t timestamp); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/src/aubuf/aubuf.c new/rem-2.6.0/src/aubuf/aubuf.c --- old/rem-2.4.0/src/aubuf/aubuf.c 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/src/aubuf/aubuf.c 2022-07-29 16:23:47.000000000 +0200 @@ -13,17 +13,18 @@ #define AUBUF_DEBUG 0 -#define AUDIO_TIMEBASE 1000000U /** Locked audio-buffer with almost zero-copy */ struct aubuf { struct list afl; - struct lock *lock; + mtx_t *lock; size_t wish_sz; size_t cur_sz; size_t max_sz; - bool filling; + size_t fill_sz; /**< To fill size */ + size_t pkt_sz; /**< Packet size */ + size_t wr_sz; /**< Written size */ bool started; uint64_t ts; @@ -91,8 +92,9 @@ mem_deref(f); } else if (af->srate && af->ch && sample_size) { - f->af.timestamp += n * AUDIO_TIMEBASE / - (af->srate * af->ch * sample_size); + + f->af.timestamp += + auframe_bytes_to_timestamp(&f->af, n); } if (n == sz) @@ -118,20 +120,20 @@ struct aubuf *ab; int err; - if (!abp || !min_sz) + if (!abp) return EINVAL; ab = mem_zalloc(sizeof(*ab), aubuf_destructor); if (!ab) return ENOMEM; - err = lock_alloc(&ab->lock); + err = mutex_alloc(&ab->lock); if (err) goto out; ab->wish_sz = min_sz; - ab->max_sz = max_sz; - ab->filling = true; + ab->max_sz = max_sz; + ab->fill_sz = min_sz; out: if (err) @@ -178,13 +180,13 @@ */ int aubuf_resize(struct aubuf *ab, size_t min_sz, size_t max_sz) { - if (!ab || !min_sz) + if (!ab) return EINVAL; - lock_write_get(ab->lock); + mtx_lock(ab->lock); ab->wish_sz = min_sz; ab->max_sz = max_sz; - lock_rel(ab->lock); + mtx_unlock(ab->lock); aubuf_flush(ab); @@ -215,7 +217,7 @@ const struct auframe *af) { struct frame *f; - size_t max_sz; + size_t sz; if (!ab || !mb) return EINVAL; @@ -228,32 +230,36 @@ if (af) f->af = *af; - lock_write_get(ab->lock); + sz = mbuf_get_left(mb); + + mtx_lock(ab->lock); + ab->pkt_sz = sz; + if (ab->fill_sz >= ab->pkt_sz) + ab->fill_sz -= ab->pkt_sz; + + if (!f->af.timestamp && f->af.srate && f->af.ch) { + f->af.timestamp = + auframe_bytes_to_timestamp(&f->af, ab->wr_sz); + } list_insert_sorted(&ab->afl, frame_less_equal, NULL, &f->le, f); - ab->cur_sz += mbuf_get_left(mb); + ab->cur_sz += sz; + ab->wr_sz += sz; - max_sz = ab->started ? ab->max_sz : ab->wish_sz + 1; - if (ab->max_sz && ab->cur_sz > max_sz) { + if (ab->max_sz && ab->cur_sz > ab->max_sz) { #if AUBUF_DEBUG - if (ab->started) { - ++ab->stats.or; - (void)re_printf("aubuf: %p overrun (cur=%zu/%zu)\n", - ab, ab->cur_sz, ab->max_sz); - } + ++ab->stats.or; + (void)re_printf("aubuf: %p overrun (cur=%zu/%zu)\n", + ab, ab->cur_sz, ab->max_sz); #endif f = list_ledata(ab->afl.head); if (f) { - ab->cur_sz -= mbuf_get_left(f->mb); + ab->cur_sz -= sz; mem_deref(f); } } - if (ab->filling && ab->cur_sz >= ab->wish_sz) - ab->filling = false; - - lock_rel(ab->lock); - + mtx_unlock(ab->lock); return 0; } @@ -271,6 +277,7 @@ struct mbuf *mb; size_t sz; size_t sample_size; + bool ajb; int err; if (!ab || !af) @@ -291,11 +298,12 @@ err = aubuf_append_auframe(ab, mb, af); - lock_write_get(ab->lock); + mtx_lock(ab->lock); mem_deref(mb); - lock_rel(ab->lock); + ajb = !ab->fill_sz && ab->ajb; + mtx_unlock(ab->lock); - if (!ab->filling && ab->ajb) + if (ajb) ajb_calc(ab->ajb, af, ab->cur_sz); return err; @@ -318,10 +326,11 @@ if (!ab || !af) return; + sz = auframe_size(af); if (!ab->ajb && ab->mode == AUBUF_ADAPTIVE) - ab->ajb = ajb_alloc(ab->silence); + ab->ajb = ajb_alloc(ab->silence, ab->wish_sz); - lock_write_get(ab->lock); + mtx_lock(ab->lock); as = ajb_get(ab->ajb, af); if (as == AJB_LOW) { #if AUBUF_DEBUG @@ -331,24 +340,35 @@ goto out; } - sz = auframe_size(af); - if (ab->cur_sz < (ab->filling ? ab->wish_sz : sz)) { + if (ab->fill_sz || ab->cur_sz < sz) { #if AUBUF_DEBUG - if (!ab->filling) { + if (!ab->fill_sz) { ++ab->stats.ur; - (void)re_printf("aubuf: %p underrun (cur=%zu)\n", - ab, ab->cur_sz); + (void)re_printf("aubuf: %p underrun " + "(cur=%zu, sz=%zu)\n", + ab, ab->cur_sz, sz); + fflush(stdout); plot_underrun(ab->ajb); } #endif - if (!ab->filling) - ajb_reset(ab->ajb); + if (!ab->fill_sz) + ajb_set_ts0(ab->ajb, 0); - filling = ab->filling; - ab->filling = true; + filling = ab->fill_sz > 0; memset(af->sampv, 0, sz); if (filling) goto out; + else + ab->fill_sz = ab->wish_sz; + } + + /* on first read drop old frames */ + while (!ab->started && ab->wish_sz && ab->cur_sz > ab->wish_sz) { + struct frame *f = list_ledata(ab->afl.head); + if (f) { + ab->cur_sz -= mbuf_get_left(f->mb); + mem_deref(f); + } } ab->started = true; @@ -362,7 +382,15 @@ } out: - lock_rel(ab->lock); + + if (ab->fill_sz && ab->fill_sz < ab->pkt_sz) { + if (ab->fill_sz >= sz) + ab->fill_sz -= sz; + else + ab->fill_sz = 0; + } + + mtx_unlock(ab->lock); } @@ -388,7 +416,7 @@ if (!ab || !ptime) return EINVAL; - lock_write_get(ab->lock); + mtx_lock(ab->lock); now = tmr_jiffies(); if (!ab->ts) @@ -402,7 +430,7 @@ ab->ts += ptime; out: - lock_rel(ab->lock); + mtx_unlock(ab->lock); if (!err) aubuf_read(ab, p, sz); @@ -421,14 +449,15 @@ if (!ab) return; - lock_write_get(ab->lock); + mtx_lock(ab->lock); list_flush(&ab->afl); - ab->filling = true; + ab->fill_sz = ab->wish_sz; ab->cur_sz = 0; + ab->wr_sz = 0; ab->ts = 0; - lock_rel(ab->lock); + mtx_unlock(ab->lock); ajb_reset(ab->ajb); } @@ -448,16 +477,16 @@ if (!ab) return 0; - lock_read_get(ab->lock); - err = re_hprintf(pf, "wish_sz=%zu cur_sz=%zu filling=%d", - ab->wish_sz, ab->cur_sz, ab->filling); + mtx_lock(ab->lock); + err = re_hprintf(pf, "wish_sz=%zu cur_sz=%zu fill_sz=%zu", + ab->wish_sz, ab->cur_sz, ab->fill_sz); #if AUBUF_DEBUG err |= re_hprintf(pf, " [overrun=%zu underrun=%zu]", ab->stats.or, ab->stats.ur); #endif - lock_rel(ab->lock); + mtx_unlock(ab->lock); return err; } @@ -477,9 +506,9 @@ if (!ab) return 0; - lock_read_get(ab->lock); + mtx_lock(ab->lock); sz = ab->cur_sz; - lock_rel(ab->lock); + mtx_unlock(ab->lock); return sz; } @@ -499,10 +528,18 @@ } +/** + * This function is for reporting that the given audio frame was dropped. Its + * timestamp is used to reset the ajb structure to avoid a jump of the computed + * jitter value + * + * @param ab Audio buffer + * @param af Audio frame + */ void aubuf_drop_auframe(struct aubuf *ab, const struct auframe *af) { if (!ab) return; - ajb_drop(ab->ajb, af); + ajb_set_ts0(ab->ajb, af->timestamp); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/src/auframe/auframe.c new/rem-2.6.0/src/auframe/auframe.c --- old/rem-2.4.0/src/auframe/auframe.c 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/src/auframe/auframe.c 2022-07-29 16:23:47.000000000 +0200 @@ -101,3 +101,11 @@ return af->level; } + + +size_t auframe_bytes_to_timestamp(const struct auframe *af, size_t n) +{ + size_t sample_size = aufmt_sample_size(af->fmt); + + return n * AUDIO_TIMEBASE / (af->srate * af->ch * sample_size); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/src/aulevel/aulevel.c new/rem-2.6.0/src/aulevel/aulevel.c --- old/rem-2.4.0/src/aulevel/aulevel.c 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/src/aulevel/aulevel.c 2022-07-29 16:23:47.000000000 +0200 @@ -1,5 +1,5 @@ /** - * @file src/aulevel.c Audio level + * @file aulevel/aulevel.c Audio level * * Copyright (C) 2017 Creytiv.com */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/src/aumix/aumix.c new/rem-2.6.0/src/aumix/aumix.c --- old/rem-2.4.0/src/aumix/aumix.c 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/src/aumix/aumix.c 2022-07-29 16:23:47.000000000 +0200 @@ -224,16 +224,20 @@ mix->ch = ch; err = mtx_init(&mix->mutex, mtx_plain); - if (err) + if (err != thrd_success) { + err = ENOMEM; goto out; + } err = cnd_init(&mix->cond); - if (err) + if (err != thrd_success) { + err = ENOMEM; goto out; + } mix->run = true; - err = thrd_create(&mix->thread, aumix_thread, mix); + err = thread_create_name(&mix->thread, "aumix", aumix_thread, mix); if (err) { mix->run = false; goto out; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rem-2.4.0/src/vidmix/vidmix.c new/rem-2.6.0/src/vidmix/vidmix.c --- old/rem-2.4.0/src/vidmix/vidmix.c 2022-06-01 14:56:24.000000000 +0200 +++ new/rem-2.6.0/src/vidmix/vidmix.c 2022-07-29 16:23:47.000000000 +0200 @@ -18,7 +18,7 @@ struct vidmix { - struct lock *rwlock; + mtx_t rwlock; struct list srcl; bool initialized; }; @@ -71,7 +71,7 @@ struct vidmix *mix = arg; if (mix->initialized) - mix->rwlock = mem_deref(mix->rwlock); + mtx_destroy(&mix->rwlock); } @@ -82,10 +82,10 @@ vidmix_source_stop(src); if (src->le.list) { - lock_write_get(src->mix->rwlock); + mtx_lock(&src->mix->rwlock); list_unlink(&src->le); clear_all(src->mix); - lock_rel(src->mix->rwlock); + mtx_unlock(&src->mix->rwlock); } mem_deref(src->frame_tx); @@ -210,7 +210,7 @@ continue; } - lock_read_get(mix->rwlock); + mtx_lock(&mix->rwlock); if (src->clear) { clear_frame(src->frame_tx); @@ -256,7 +256,7 @@ ++idx; } - lock_rel(mix->rwlock); + mtx_unlock(&mix->rwlock); src->fh((uint32_t)ts * 90, src->frame_tx, src->arg); @@ -291,7 +291,7 @@ if (ts > now) continue; - lock_read_get(mix->rwlock); + mtx_lock(&mix->rwlock); for (le=mix->srcl.head; le; le=le->next) { @@ -304,7 +304,7 @@ break; } - lock_rel(mix->rwlock); + mtx_unlock(&mix->rwlock); ts += src->fint; } @@ -334,9 +334,11 @@ if (!mix) return ENOMEM; - err = lock_alloc(&mix->rwlock); - if (err) + err = mtx_init(&mix->rwlock, mtx_plain); + if (err != thrd_success) { + err = ENOMEM; goto out; + } mix->initialized = true; @@ -384,8 +386,10 @@ src->arg = arg; err = mtx_init(&src->mutex, mtx_plain); - if (err) + if (err != thrd_success) { + err = ENOMEM; goto out; + } if (sz) { err = vidframe_alloc(&src->frame_tx, VID_FMT_YUV420P, sz); @@ -461,7 +465,7 @@ if (!src->le.list && !enable) return; - lock_write_get(src->mix->rwlock); + mtx_lock(&src->mix->rwlock); if (enable) { if (src->frame_rx) @@ -475,7 +479,7 @@ clear_all(src->mix); - lock_rel(src->mix->rwlock); + mtx_unlock(&src->mix->rwlock); } @@ -498,12 +502,11 @@ src->run = true; - err = thrd_create(&src->thread, - src->content ? content_thread : vidmix_thread, - src); - if (err) { + err = thread_create_name(&src->thread, "vidmix", + src->content ? content_thread : vidmix_thread, + src); + if (err) src->run = false; - } return err; } @@ -655,7 +658,7 @@ struct le *le; unsigned i; - lock_read_get(src->mix->rwlock); + mtx_lock(&src->mix->rwlock); for (le=src->mix->srcl.head, i=1; le; le=le->next) { @@ -673,7 +676,7 @@ } } - lock_rel(src->mix->rwlock); + mtx_unlock(&src->mix->rwlock); } if (focus && focus == src->focus) @@ -707,17 +710,17 @@ if (err) return; - lock_write_get(src->mix->rwlock); + mtx_lock(&src->mix->rwlock); mem_deref(src->frame_rx); src->frame_rx = frm; clear_all(src->mix); - lock_rel(src->mix->rwlock); + mtx_unlock(&src->mix->rwlock); } - lock_write_get(src->mix->rwlock); + mtx_lock(&src->mix->rwlock); vidframe_copy(src->frame_rx, frame); - lock_rel(src->mix->rwlock); + mtx_unlock(&src->mix->rwlock); }