From patchwork Sun Jul 30 22:11:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Niedermayer X-Patchwork-Id: 43030 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7927:b0:130:ccc6:6c4b with SMTP id b39csp2030292pzg; Sun, 30 Jul 2023 15:11:57 -0700 (PDT) X-Google-Smtp-Source: APBJJlHw3VqNaCgMtMDj6Aj0sJqw/pPQadPvPefGZFIgXmXzo8gJt73ySfqvKOloJyoPMf1CNJ3H X-Received: by 2002:a17:906:8457:b0:99b:cd1a:a453 with SMTP id e23-20020a170906845700b0099bcd1aa453mr6383837ejy.3.1690755117717; Sun, 30 Jul 2023 15:11:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690755117; cv=none; d=google.com; s=arc-20160816; b=McZIe/eFd0kIvexpqHjRG3f21BDhilV+rkciQyJWazg828qxxf9ST4Dmo0u0+ZmZtb TwBJUYMLBvE87FI1tBQGNbsNSmiFTrs/F3wxYur1jy2FXTD3FQdwGB4pLcEvLSBLt7Wd yVfaiObC4LrHtusGhaPw0GfYZlZTukP6UW5DpxVVGX6SBb3OTBCZYrzEoOZ0QPelY3xd nl5xYMOjDPKaQNcla6DWdPx1iUOyAzYGiyGaK43f/R9zM5lbwYlaJ3NDDculqbkPfI2O gqm4QcmcBmlV5wqYRFK39HRvKSlH0FOUDxRcUM5Um3A5zAkovM94Ag2izAh1b4pq8CZd FuRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:delivered-to; bh=savoN4hpEelAoRg9tGEM0yMX0Qh/eCSKFNaGiB0A98A=; fh=YYwLYmpaV0Fpw/rxmSKNRLS2XzDkAlGbHATiKOPtZrY=; b=WbYbcG3eWa0GgMEuVFeXhlv+WZcEbWm4J9n086dctrQQJvOGGcVitht0hTCiVUhAVk tiMQ69HTjQF1aqWQi/hDVodbYerKkIM2Wd1S+IYvkTrujmUCyERcix97dFdzgmiAuGqx y9JHDSt6fB2wWzKzjA7Wt8uHrOTAvvBduCj6Mz3zJmfq+VSAGQnyGP6fEOHAi7JQwcKf tBCuCUFhG3uRZ5KxOAHSXya04gyK3VMThUUo4aFXfIxuOprxSJKgLsJ6PI7LyEpTI0Ux R2E7NiZi1cTH73kNP37W0pUpkx56XrRb7kQfCw1lXyfNLShttPZoz4BPM11sAFIk19J2 qLKQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id w6-20020a1709064a0600b0098e2aa0bb92si6070253eju.137.2023.07.30.15.11.57; Sun, 30 Jul 2023 15:11:57 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 966AC68C36E; Mon, 31 Jul 2023 01:11:43 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B352368C548 for ; Mon, 31 Jul 2023 01:11:35 +0300 (EEST) Received: by mail.gandi.net (Postfix) with ESMTPSA id CDEAB1C0002 for ; Sun, 30 Jul 2023 22:11:34 +0000 (UTC) From: Michael Niedermayer To: FFmpeg development discussions and patches Date: Mon, 31 Jul 2023 00:11:21 +0200 Message-Id: <20230730221131.1205193-2-michael@niedermayer.cc> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230730221131.1205193-1-michael@niedermayer.cc> References: <20230730221131.1205193-1-michael@niedermayer.cc> MIME-Version: 1.0 X-GND-Sasl: michael@niedermayer.cc Subject: [FFmpeg-devel] [PATCH 02/12] avradio/avformat/sdrdemux: Move Software AGC into buffer thread X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: B5wXE+wb9sH9 This allows the AGC to act with less latency Signed-off-by: Michael Niedermayer --- libavformat/sdr.h | 1 - libavformat/sdrdemux.c | 77 ++++++++++++++++++++++++------------------ 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/libavformat/sdr.h b/libavformat/sdr.h index 1f2d3a49ab..1bf8fbef79 100644 --- a/libavformat/sdr.h +++ b/libavformat/sdr.h @@ -161,7 +161,6 @@ typedef struct SDRContext { float agc_max_headroom; float agc_max_headroom_time; int agc_low_time; - atomic_int wanted_gain; int sdr_adcc; int64_t bandwidth; int64_t last_pts; diff --git a/libavformat/sdrdemux.c b/libavformat/sdrdemux.c index 4bde431e17..e5ee4e80f5 100644 --- a/libavformat/sdrdemux.c +++ b/libavformat/sdrdemux.c @@ -1475,6 +1475,7 @@ static void *soapy_needs_bigger_buffers_worker(SDRContext *sdr) unsigned block_counter = 0; int64_t local_wanted_freq = 0; int64_t last_wanted_freq = 0; + float wanted_gain = (sdr->min_gain + sdr->max_gain) / 2; float agc_gain = 0; sdr->remaining_file_block_size = 0; @@ -1485,7 +1486,6 @@ static void *soapy_needs_bigger_buffers_worker(SDRContext *sdr) FIFOElement fifo_element; int remaining, ret; int empty_blocks, full_blocks; - float wanted_gain = atomic_load(&sdr->wanted_gain) / 65536.0; int64_t wanted_freq = atomic_load(&sdr->wanted_freq); int seek_direction = atomic_load(&sdr->seek_direction); @@ -1551,6 +1551,49 @@ static void *soapy_needs_bigger_buffers_worker(SDRContext *sdr) remaining -= ret; } + if (sdr->sdr_gain == GAIN_SW_AGC) { + float inmax = 0; + int inmax1 = 0; + // We only check 25% of the data to safe computations + int start = 3*sdr->block_size / 4; + int end = 5*sdr->block_size / 4; + if (sdr->sample_size == 2) { + const int8_t *halfblock = fifo_element.halfblock; + for (int i = start; i < end; i++) { + int v = FFMAX(FFABS(halfblock[i]), FFABS(halfblock[i])); + inmax1 = FFMAX(inmax1, v); + } + } else if (sdr->sample_size == 4) { + const int16_t *halfblock = fifo_element.halfblock; + for (int i = start; i < end; i++) { + int v = FFMAX(FFABS(halfblock[i]), FFABS(halfblock[i])); + inmax1 = FFMAX(inmax1, v); + } + } else { + const float *halfblock = fifo_element.halfblock; + for (int i = start; i < end; i++) { + float v = fmaxf(fabsf(halfblock[i]), fabsf(halfblock[i])); + inmax = fmaxf(inmax, v); + } + } + inmax = fmaxf(inmax, inmax1 / sdr->sample_scale); + + if (inmax > 1.0 - sdr->agc_min_headroom && wanted_gain > sdr->min_gain) { + //according to docs this is a dB scale, in reality it beheaves differnt to that + //Because of this we will try to just make small changes and not assume too much + wanted_gain = FFMIN(wanted_gain, FFMAX(agc_gain - 1.0, agc_gain * 0.9)); + + sdr->agc_low_time = 0; + } else if (inmax < 1.0 - sdr->agc_max_headroom && wanted_gain < sdr->max_gain) { + sdr->agc_low_time += sdr->block_size; + if (sdr->agc_low_time > sdr->agc_max_headroom_time * sdr->sdr_sample_rate) { + sdr->agc_low_time = 0; + wanted_gain = FFMAX(wanted_gain, FFMIN(agc_gain + 1.0, agc_gain * 1.1)); + } + } else + sdr->agc_low_time = 0; + } + inject_block_into_fifo(sdr, sdr->full_block_fifo, &fifo_element, "block fifo overflow, discarding block\n"); } av_assert0(atomic_load(&sdr->close_requested) == 1); @@ -1724,7 +1767,6 @@ int avpriv_sdr_common_init(AVFormatContext *s) atomic_init(&sdr->close_requested, 0); atomic_init(&sdr->seek_direction, 0); atomic_init(&sdr->wanted_freq, sdr->user_wanted_freq); - atomic_init(&sdr->wanted_gain, lrint((sdr->min_gain + sdr->max_gain) * 65536 / 2)); ret = pthread_mutex_init(&sdr->mutex, NULL); if (ret) { av_log(s, AV_LOG_ERROR, "pthread_mutex_init failed: %s\n", strerror(ret)); @@ -2021,37 +2063,6 @@ process_next_block: } } - float smaller_block_gain = FFMIN(fifo_element[0].gain, fifo_element[1].gain); - float bigger_block_gain = FFMAX(fifo_element[0].gain, fifo_element[1].gain); - - if (sdr->sdr_gain == GAIN_SW_AGC) { - float inmax = 0; - float wanted_gain = atomic_load(&sdr->wanted_gain) / 65536.0; - // We only check 25% of the data to safe computations - int start = 3*sdr->block_size / 4; - int end = 5*sdr->block_size / 4; - for (i = start; i < end; i++) { - float v = fmaxf(fabsf(sdr->windowed_block[i].re), fabsf(sdr->windowed_block[i].im)); - inmax = fmaxf(inmax, v); - } - - if (inmax > 1.0 - sdr->agc_min_headroom && wanted_gain > sdr->min_gain) { - //according to docs this is a dB scale, in reality it beheaves differnt to that - //Because of this we will try to just make small changes and not assume too much - wanted_gain = FFMIN(wanted_gain, FFMAX(smaller_block_gain - 1.0, smaller_block_gain * 0.9)); - - sdr->agc_low_time = 0; - } else if (inmax < 1.0 - sdr->agc_max_headroom && wanted_gain < sdr->max_gain) { - sdr->agc_low_time += sdr->block_size; - if (sdr->agc_low_time > sdr->agc_max_headroom_time * sdr->sdr_sample_rate) { - sdr->agc_low_time = 0; - wanted_gain = FFMAX(wanted_gain, FFMIN(bigger_block_gain + 1.0, bigger_block_gain * 1.1)); - } - } else - sdr->agc_low_time = 0; - atomic_store(&sdr->wanted_gain, (int)lrint(wanted_gain * 65536)); - } - inject_block_into_fifo(sdr, sdr->empty_block_fifo, &fifo_element[0], "Cannot pass next buffer, freeing it\n"); #ifdef SYN_TEST //synthetic test signal static int64_t synp=0;