From: Michael Niedermayer <michael@niedermayer.cc>
To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
Subject: [FFmpeg-devel] [PATCH 02/12] avradio/avformat/sdrdemux: Move Software AGC into buffer thread
Date: Mon, 31 Jul 2023 00:11:21 +0200
Message-ID: <20230730221131.1205193-2-michael@niedermayer.cc> (raw)
In-Reply-To: <20230730221131.1205193-1-michael@niedermayer.cc>
This allows the AGC to act with less latency
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
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;
--
2.31.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2023-07-30 22:11 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-30 22:11 [FFmpeg-devel] [PATCH 01/12] avradio/avformat/sdrdemux: Move agc_gain into local variable Michael Niedermayer
2023-07-30 22:11 ` Michael Niedermayer [this message]
2023-07-30 22:11 ` [FFmpeg-devel] [PATCH 03/12] avradio/avdevice/sdrindev: Soapy / RTLSDR ignores gain in direct sampling mode Michael Niedermayer
2023-07-30 22:11 ` [FFmpeg-devel] [PATCH 04/12] avradio/avformat/sdrdemux: only update agc_gain on success Michael Niedermayer
2023-07-30 22:11 ` [FFmpeg-devel] [PATCH 05/12] avradio/avformat/sdrdemux: delay station search on AGC adjust Michael Niedermayer
2023-07-30 22:11 ` [FFmpeg-devel] [PATCH 06/12] avradio/avformat/sdrdemux: run clip check on the correct samples Michael Niedermayer
2023-07-30 22:11 ` [FFmpeg-devel] [PATCH 07/12] avradio/avformat/sdrdemux: Avoid uninitialized memory on mono -> stereo switch Michael Niedermayer
2023-07-30 22:11 ` [FFmpeg-devel] [PATCH 08/12] avradio/avformat/sdrdemux: set wanted gain also when manually set Michael Niedermayer
2023-07-30 22:11 ` [FFmpeg-devel] [PATCH 09/12] avradio/avformat/sdrdemux: dont use a fuction name as local variable Michael Niedermayer
2023-07-30 22:11 ` [FFmpeg-devel] [PATCH 10/12] avradio/avformat/sdrdemux: fix off by 2 FM bandwidth error Michael Niedermayer
2023-07-30 22:11 ` [FFmpeg-devel] [PATCH 11/12] avradio/avformat/sdrdemux: fix FM block size Michael Niedermayer
2023-07-30 22:11 ` [FFmpeg-devel] [PATCH 12/12] avradio/avformat/sdrdemux: replace heuristic FM scaling by logic Michael Niedermayer
2023-07-30 22:26 ` [FFmpeg-devel] [PATCH 01/12] avradio/avformat/sdrdemux: Move agc_gain into local variable Paul B Mahol
2023-08-10 21:03 ` Michael Niedermayer
2023-08-10 23:03 ` Paul B Mahol
2023-09-08 13:24 ` Michael Niedermayer
2023-09-09 10:34 ` Paul B Mahol
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230730221131.1205193-2-michael@niedermayer.cc \
--to=michael@niedermayer.cc \
--cc=ffmpeg-devel@ffmpeg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git