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