* [FFmpeg-devel] [PATCH 02/12] avradio/rds: Implement burst error decoder
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
@ 2023-07-11 21:19 ` Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 03/12] avradio/rds: Keep track of program_id Michael Niedermayer
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/rds.c | 55 ++++++++++++++++++++++++++++++------------------
1 file changed, 34 insertions(+), 21 deletions(-)
diff --git a/libavradio/rds.c b/libavradio/rds.c
index dd9a934c3c..2cb7942bbd 100644
--- a/libavradio/rds.c
+++ b/libavradio/rds.c
@@ -35,29 +35,42 @@
#include "libavformat/avformat.h"
#include "libavformat/demux.h"
+#define MAX_BURST 5 // Tradeoff between undetected errors and correction capacity values from 2 to 5 are reasonable
+
+static int burst_len(unsigned u)
+{
+ if (!u)
+ return 0;
+
+ while(!(u&1))
+ u>>=1;
+ return 1+av_log2(u);
+}
+
/**
* Check and correct RDS block
* @param[out] group the data bits are returned here
* @param block block nu,ber (0 to 3)
* @return 1 if correctable single bit error, 0 if no error, >99 if non correctable errors
*/
-static int check_rds_block(uint16_t group[4], const float diff[104], int block)
+static int check_rds_block(Station *station, uint16_t group[4], const float diff[104], const int block)
{
#define RDS_G 0x5B9 //101 1011 1001
static const uint16_t offset[4] = {0x0FC, 0x198, 0x168, 0x1B4};
unsigned codeword = 0;
- unsigned syndrom = 0;
- //we carry floats through to here so we can do a soft decission decoder
- //ATM lets just do hard decission decoding that should be more than good enough
+ unsigned syndrom = 0;
+ const float *blockdiff = diff + block*26;
//FIXME we could do this more efficiently but does it matter?
for(int i=0; i<26; i++) {
- int bit = (diff[i + block*26]<0);
+ int bit = blockdiff[i] < 0;
+
codeword += codeword + bit;
syndrom += syndrom + bit;
if (syndrom & (1<<10))
syndrom ^= RDS_G;
}
+
if (block==2 && (group[1]&0x800)) {
syndrom ^= 0x350;
}else
@@ -66,25 +79,24 @@ static int check_rds_block(uint16_t group[4], const float diff[104], int block)
group[block] = codeword >> 10;
- // try correcting some basic errors
- if (syndrom) {
- for (unsigned e = 1; e <= 2; e ++) {
- unsigned mask = 255 >> (8-e);
- unsigned syndrom1 = mask;
- for(int i=0; i<27-e; i++) {
- if (syndrom == syndrom1) {
- group[block] ^= (mask<<i) >> 10;
- return e;
+ // try correcting the most common error patterns
+ for (int i=0; i<27-MAX_BURST; i++) {
+ if (!(syndrom>>MAX_BURST)) {
+ int ret = burst_len(syndrom);
+ group[block] ^= (syndrom << i) >> 10;
+
+ return ret;
}
- syndrom1 += syndrom1;
- if (syndrom1 & (1<<10))
- syndrom1 ^= RDS_G;
}
+
+ return ret;
}
- return 100; // this is a good place do a 2nd pass with a soft decssion multi bit decoder
+ if (syndrom&1)
+ syndrom ^= RDS_G;
+ syndrom >>= 1;
}
- return 0;
+ return 20;
}
static int decode_rds_group(SDRContext *sdr, SDRStream *sst, uint16_t group[4])
@@ -131,6 +143,7 @@ int ff_sdr_decode_rds(SDRContext *sdr, SDRStream *sst, AVComplexFloat *signal)
uint16_t group[4];
int64_t num_step_in_p2 = sdr->sdr_sample_rate * (int64_t)sst->block_size_p2;
int64_t den_step_on_p2 = sdr->block_size * 2375LL;
+ Station *station = sst->station;
#define IDX(I) ((I)*num_step_in_p2/den_step_on_p2)
av_assert0(sst->rds_ring_pos <= sst->rds_ring_size - 2*sst->block_size_p2);
@@ -171,7 +184,7 @@ int ff_sdr_decode_rds(SDRContext *sdr, SDRStream *sst, AVComplexFloat *signal)
for (phase = 0; phase < 104; phase++) {
int error = 0;
for (int block = 0; block < 4; block++) {
- error += check_rds_block(group, diff + phase, block);
+ error += check_rds_block(station, group, diff + phase, block);
}
if (error < best_errors) {
best_errors = error;
@@ -184,7 +197,7 @@ int ff_sdr_decode_rds(SDRContext *sdr, SDRStream *sst, AVComplexFloat *signal)
if (best_errors < 10) {
int error = 0;
for (int block = 0; block < 4; block++) {
- error += check_rds_block(group, diff + best_phase, block);
+ error += check_rds_block(station, group, diff + best_phase, block);
}
//have to recheck because of floats
if (error < 10) {
--
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".
^ permalink raw reply [flat|nested] 13+ messages in thread
* [FFmpeg-devel] [PATCH 03/12] avradio/rds: Keep track of program_id
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 02/12] avradio/rds: Implement burst error decoder Michael Niedermayer
@ 2023-07-11 21:19 ` Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 04/12] avradio/sdr: Move rds_ring to Station Michael Niedermayer
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
This allows detecting more damaged blocks
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/rds.c | 16 ++++++++++++++++
libavradio/sdr.h | 1 +
2 files changed, 17 insertions(+)
diff --git a/libavradio/rds.c b/libavradio/rds.c
index 2cb7942bbd..dc7124cab3 100644
--- a/libavradio/rds.c
+++ b/libavradio/rds.c
@@ -85,7 +85,13 @@ static int check_rds_block(Station *station, uint16_t group[4], const float diff
int ret = burst_len(syndrom);
group[block] ^= (syndrom << i) >> 10;
+ if (block == 0 && station->program_id[0]) {
+ if (group[0] == station->program_id[0]) {
return ret;
+ } else if (group[0] == station->program_id[1]) {
+ return ret;
+ } else if (ret) {
+ return 20; //PI change is uncommon, so dont accept this in a damaged block, PI is repeated alot so we can wait for a clean block
}
}
@@ -108,6 +114,16 @@ static int decode_rds_group(SDRContext *sdr, SDRStream *sst, uint16_t group[4])
int tp = group[1] & 0x400;
int pty= (group[1] >> 5) & 0x1F;
+ if (station->program_id[0] && station->program_id[0] != pi)
+ av_log(sdr->avfmt, AV_LOG_INFO, "PI changed to %X\n", pi);
+
+ if (station->program_id[1] == pi) {
+ FFSWAP(int, station->program_id[1], station->program_id[0]);
+ } else if (station->program_id[0] != pi) {
+ station->program_id[1] = pi;
+ return 0; // skip first packet with new PI, likely its just damaged
+ }
+
switch(a) {
case 0:
AV_WB16(station->name + 2*(group[1]&3), group[3]);
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 212358fad9..b83264ae0d 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -74,6 +74,7 @@ typedef struct Station {
char name[9];
char radiotext[65];
char programm_type_name[9];
+ int program_id[2];
enum Modulation modulation;
double frequency;
int nb_frequency; ///< number of detections which are used to compute the frequency
--
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".
^ permalink raw reply [flat|nested] 13+ messages in thread
* [FFmpeg-devel] [PATCH 04/12] avradio/sdr: Move rds_ring to Station
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 02/12] avradio/rds: Implement burst error decoder Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 03/12] avradio/rds: Keep track of program_id Michael Niedermayer
@ 2023-07-11 21:19 ` Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 05/12] avradio/rds: move phase 2 window to main context Michael Niedermayer
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Other changes are needed to be done in this commit because of
dependancies
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/rds.c | 36 +++++++++---------
libavradio/sdr.h | 12 +++---
libavradio/sdrdemux.c | 88 ++++++++++++++++++++++++-------------------
3 files changed, 74 insertions(+), 62 deletions(-)
diff --git a/libavradio/rds.c b/libavradio/rds.c
index dc7124cab3..e16685be18 100644
--- a/libavradio/rds.c
+++ b/libavradio/rds.c
@@ -105,9 +105,8 @@ static int check_rds_block(Station *station, uint16_t group[4], const float diff
return 20;
}
-static int decode_rds_group(SDRContext *sdr, SDRStream *sst, uint16_t group[4])
+static int decode_rds_group(SDRContext *sdr, Station *station, uint16_t group[4])
{
- Station *station = sst->station;
int pi = group[0];
int a = group[1] >> 12;
int b = group[1] & 0x800;
@@ -154,26 +153,25 @@ static int decode_rds_group(SDRContext *sdr, SDRStream *sst, uint16_t group[4])
int ff_sdr_decode_rds(SDRContext *sdr, SDRStream *sst, AVComplexFloat *signal)
{
int i, phase;
- float (*ring)[2] = sst->rds_ring;
+ Station *station = sst->station;
+ float (*ring)[2] = station->rds_ring;
float diff[2*104 - 1];
uint16_t group[4];
- int64_t num_step_in_p2 = sdr->sdr_sample_rate * (int64_t)sst->block_size_p2;
+ int64_t num_step_in_p2 = sdr->sdr_sample_rate * (int64_t)sdr->fm_block_size_p2;
int64_t den_step_on_p2 = sdr->block_size * 2375LL;
- Station *station = sst->station;
#define IDX(I) ((I)*num_step_in_p2/den_step_on_p2)
-
- av_assert0(sst->rds_ring_pos <= sst->rds_ring_size - 2*sst->block_size_p2);
+ av_assert0(station->rds_ring_pos <= sdr->rds_ring_size - 2*sdr->fm_block_size_p2);
//For reasons that are beyond me, RDS spec allows inphase and quadrature so we have to compute and check both
- for (int i=0; i < sst->block_size_p2; i++) {
- ring[ sst->rds_ring_pos + i ][0] += signal[i].re * sst->window_p2[i];
- ring[ sst->rds_ring_pos + i + sst->block_size_p2 ][0] = signal[i + sst->block_size_p2].re * sst->window_p2[i + sst->block_size_p2];
- ring[ sst->rds_ring_pos + i ][1] += signal[i].im * sst->window_p2[i];
- ring[ sst->rds_ring_pos + i + sst->block_size_p2 ][1] = signal[i + sst->block_size_p2].im * sst->window_p2[i + sst->block_size_p2];
+ for (int i=0; i < sdr->fm_block_size_p2; i++) {
+ ring[ station->rds_ring_pos + i ][0] += signal[i].re * sst->window_p2[i];
+ ring[ station->rds_ring_pos + i + sdr->fm_block_size_p2 ][0] = signal[i + sdr->fm_block_size_p2].re * sst->window_p2[i + sdr->fm_block_size_p2];
+ ring[ station->rds_ring_pos + i ][1] += signal[i].im * sst->window_p2[i];
+ ring[ station->rds_ring_pos + i + sdr->fm_block_size_p2 ][1] = signal[i + sdr->fm_block_size_p2].im * sst->window_p2[i + sdr->fm_block_size_p2];
}
- sst->rds_ring_pos += sst->block_size_p2;
+ station->rds_ring_pos += sdr->fm_block_size_p2;
- while (sst->rds_ring_pos > IDX(2) + IDX(4*104-1)) {
+ while (station->rds_ring_pos > IDX(2) + IDX(4*104-1)) {
int best_phase;
float best_amplitude = -1;
for (phase = 0; phase < 2*IDX(2); phase++) {
@@ -217,16 +215,16 @@ int ff_sdr_decode_rds(SDRContext *sdr, SDRStream *sst, AVComplexFloat *signal)
}
//have to recheck because of floats
if (error < 10) {
- decode_rds_group(sdr, sst, group);
+ decode_rds_group(sdr, station, group);
}
}
int step = IDX(2*(best_phase + 103));
- av_assert0(sst->rds_ring_pos >= step);
- memmove(ring, ring + step, (sst->rds_ring_pos + sst->block_size_p2 - step) * sizeof(*sst->rds_ring));
- sst->rds_ring_pos -= step;
+ av_assert0(station->rds_ring_pos >= step);
+ memmove(ring, ring + step, (station->rds_ring_pos + sdr->fm_block_size_p2 - step) * sizeof(*station->rds_ring));
+ station->rds_ring_pos -= step;
}
- av_assert0 (sst->rds_ring_pos + 2*sst->block_size_p2 <= sst->rds_ring_size);
+ av_assert0 (station->rds_ring_pos + 2*sdr->fm_block_size_p2 <= sdr->rds_ring_size);
return 0;
}
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index b83264ae0d..7d951334f9 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -79,7 +79,6 @@ typedef struct Station {
double frequency;
int nb_frequency; ///< number of detections which are used to compute the frequency
int64_t bandwidth;
- int64_t bandwidth_p2;
float score;
int in_station_list; ///< non zero if this station is in the station list
int timeout; //since how many blocks was this detectable but not detected
@@ -88,6 +87,9 @@ typedef struct Station {
int detection_per_mix_frequency[HISTOGRAMM_SIZE];
int non_detection_per_mix_frequency[HISTOGRAMM_SIZE];
+ float (*rds_ring)[2];
+ int rds_ring_pos;
+
struct SDRStream *stream;
} Station;
@@ -104,7 +106,6 @@ typedef struct SDRStream {
av_tx_fn fft;
av_tx_fn ifft_p2;
int block_size;
- int block_size_p2;
int processing_index;
float *out_buf;
AVComplexFloat *block;
@@ -113,9 +114,6 @@ typedef struct SDRStream {
AVComplexFloat *iside;
float *window;
float *window_p2;
- float (*rds_ring)[2];
- int rds_ring_size;
- int rds_ring_pos;
Station *station;
float am_amplitude;
@@ -162,6 +160,10 @@ typedef struct SDRContext {
int sample_size;
double sample_scale;
+ int64_t fm_bandwidth_p2;
+ int fm_block_size_p2;
+ int rds_ring_size;
+
int am_mode; ///< AMMode but using int for generic option access
int emphasis_mode;
int am_fft_ref;
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index a37018fd2f..762328aebe 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -101,6 +101,8 @@ static void free_station(Station *station)
{
if (station->stream)
station->stream->station = NULL;
+
+ av_freep(&station->rds_ring);
av_free(station);
}
@@ -174,7 +176,6 @@ static int create_station(SDRContext *sdr, Station *candidate_station) {
enum Modulation modulation = candidate_station->modulation;
double freq = candidate_station->frequency;
int64_t bandwidth = candidate_station->bandwidth;
- int64_t bandwidth_p2 = candidate_station->bandwidth_p2;
float score = candidate_station->score;
void *tmp;
int i;
@@ -277,7 +278,7 @@ static int create_station(SDRContext *sdr, Station *candidate_station) {
candidate_station->in_station_list = 1;
- av_log(sdr, AV_LOG_INFO, "create_station %d f:%f bw:%"PRId64"/%"PRId64" score: %f\n", modulation, freq, bandwidth, bandwidth_p2, score);
+ av_log(sdr, AV_LOG_INFO, "create_station %d f:%f bw:%"PRId64" score: %f\n", modulation, freq, bandwidth, score);
return 1;
}
@@ -373,7 +374,7 @@ static void decay_stations(SDRContext *sdr)
}
}
-static int create_candidate_station(SDRContext *sdr, enum Modulation modulation, double freq, int64_t bandwidth, int64_t bandwidth_p2, float score) {
+static int create_candidate_station(SDRContext *sdr, enum Modulation modulation, double freq, int64_t bandwidth, float score) {
Station *station;
void *tmp;
struct AVTreeNode *next = NULL;
@@ -391,10 +392,20 @@ static int create_candidate_station(SDRContext *sdr, enum Modulation modulation,
}
if (!nb_stations) {
+ double block_time = sdr->block_size / (double)sdr->sdr_sample_rate;
station = av_mallocz(sizeof(*station));
if (!station)
return AVERROR(ENOMEM);
station->frequency = freq;
+
+
+ if (!sdr->rds_ring_size)
+ sdr->rds_ring_size = ceil((2*105 / 1187.5 + 2.0*block_time) * sdr->fm_block_size_p2 / block_time);
+
+ station->rds_ring = av_mallocz(sizeof(*station->rds_ring ) * sdr->rds_ring_size);
+
+ if (!station->rds_ring)
+ goto fail;
} else {
station = station_list[0];
// We will update the frequency so we need to reinsert
@@ -407,7 +418,6 @@ static int create_candidate_station(SDRContext *sdr, enum Modulation modulation,
station->detection_per_mix_frequency[histogram_index(sdr, freq)] ++;
station->modulation = modulation;
station->bandwidth = bandwidth;
- station->bandwidth_p2 = bandwidth_p2;
station->score = score;
tmp = tree_insert(&sdr->station_root, station, station_cmp, &next);
@@ -418,6 +428,10 @@ static int create_candidate_station(SDRContext *sdr, enum Modulation modulation,
av_freep(&next);
return 1;
+fail: // only call from the branch that allocated station
+ av_freep(&station->rds_ring);
+ av_freep(&station);
+ return AVERROR(ENOMEM);
}
static void probe_common(SDRContext *sdr)
@@ -564,7 +578,7 @@ static int probe_am(SDRContext *sdr)
continue;
}
- create_candidate_station(sdr, AM, INDEX2F(peak_i), bandwidth_f, 0, score);
+ create_candidate_station(sdr, AM, INDEX2F(peak_i), bandwidth_f, score);
}
}
}
@@ -836,7 +850,6 @@ static int probe_fm(SDRContext *sdr)
{
int i;
int bandwidth_f = 180*1000;
- int bandwidth_p2 = 18*1000; //phase 2 bandwidth
int half_bw_i = bandwidth_f * (int64_t)sdr->block_size / sdr->sdr_sample_rate;
float last_score[3] = {FLT_MAX, FLT_MAX, FLT_MAX};
int border_i = (sdr->sdr_sample_rate - FFMIN(sdr->bandwidth, sdr->sdr_sample_rate*7/8)) * sdr->block_size / sdr->sdr_sample_rate;
@@ -912,7 +925,7 @@ static int probe_fm(SDRContext *sdr)
f2 = f3;
}
- create_candidate_station(sdr, FM, f2, bandwidth_f, bandwidth_p2, score);
+ create_candidate_station(sdr, FM, f2, bandwidth_f, score);
}
}
}
@@ -932,7 +945,7 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
float *newbuf;
float scale;
int sample_rate = sdr->sdr_sample_rate * (int64_t)sst->block_size / sdr->block_size;
- int sample_rate_p2 = sdr->sdr_sample_rate * (int64_t)sst->block_size_p2 / sdr->block_size;
+ int sample_rate_p2 = sdr->sdr_sample_rate * (int64_t)sdr->fm_block_size_p2 / sdr->block_size;
int ret, i;
float clip = 1.0;
int carrier19_i = 2L*sst->block_size*19000 / sample_rate;
@@ -972,7 +985,7 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
sst->iblock[i].re = 0;
sst->iblock[i].im = 0;
- av_assert0(sst->block_size_p2 * 2 < sst->block_size);
+ av_assert0(sdr->fm_block_size_p2 * 2 < sst->block_size);
//FIXME this only needs to be a RDFT
//CONSIDER, this and in fact alot can be done with bandpass and lowpass filters instead of FFTs, find out which is better
//CONSIDER synthesizing the carrier instead of IFFT, we have all parameters for that
@@ -984,39 +997,39 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
if (carrier19_i >= 0) {
i = sst->block_size;
- memset(sst->block + i, 0, 2*sst->block_size_p2 * sizeof(AVComplexFloat));
+ memset(sst->block + i, 0, 2*sdr->fm_block_size_p2 * sizeof(AVComplexFloat));
memcpy(sst->block + i, sst->block + carrier19_i, sizeof(AVComplexFloat)*(W+1));
- memcpy(sst->block + i + 2*sst->block_size_p2 - W, sst->block + carrier19_i - W, sizeof(AVComplexFloat)*W);
+ memcpy(sst->block + i + 2*sdr->fm_block_size_p2 - W, sst->block + carrier19_i - W, sizeof(AVComplexFloat)*W);
sst->ifft_p2(sst->ifft_p2_ctx, sst->icarrier, sst->block + i, sizeof(AVComplexFloat));
memcpy(sst->block + i, sst->block + 3*carrier19_i, sizeof(AVComplexFloat)*len2_4_i);
- memcpy(sst->block + i + 2*sst->block_size_p2 - len2_4_i, sst->block + 3*carrier19_i - len2_4_i, sizeof(AVComplexFloat)*len2_4_i);
+ memcpy(sst->block + i + 2*sdr->fm_block_size_p2 - len2_4_i, sst->block + 3*carrier19_i - len2_4_i, sizeof(AVComplexFloat)*len2_4_i);
sst->ifft_p2(sst->ifft_p2_ctx, sst->iside , sst->block + i, sizeof(AVComplexFloat));
- synchronous_am_demodulationN(sst->iside, sst->icarrier, sst->window_p2, 2*sst->block_size_p2, 3);
+ synchronous_am_demodulationN(sst->iside, sst->icarrier, sst->window_p2, 2*sdr->fm_block_size_p2, 3);
ff_sdr_decode_rds(sdr, sst, sst->iside);
memcpy(sst->block + i, sst->block + 2*carrier19_i, sizeof(AVComplexFloat)*len17_i);
- memcpy(sst->block + i + 2*sst->block_size_p2 - len17_i, sst->block + 2*carrier19_i - len17_i, sizeof(AVComplexFloat)*len17_i);
- apply_deemphasis(sdr, sst->block + i, sst->block_size_p2, sample_rate_p2, + 1);
- apply_deemphasis(sdr, sst->block + i + 2*sst->block_size_p2, sst->block_size_p2, sample_rate_p2, - 1);
+ memcpy(sst->block + i + 2*sdr->fm_block_size_p2 - len17_i, sst->block + 2*carrier19_i - len17_i, sizeof(AVComplexFloat)*len17_i);
+ apply_deemphasis(sdr, sst->block + i, sdr->fm_block_size_p2, sample_rate_p2, + 1);
+ apply_deemphasis(sdr, sst->block + i + 2*sdr->fm_block_size_p2, sdr->fm_block_size_p2, sample_rate_p2, - 1);
sst->ifft_p2(sst->ifft_p2_ctx, sst->iside , sst->block + i, sizeof(AVComplexFloat));
- synchronous_am_demodulationN(sst->iside, sst->icarrier, sst->window_p2, 2*sst->block_size_p2, 2);
+ synchronous_am_demodulationN(sst->iside, sst->icarrier, sst->window_p2, 2*sdr->fm_block_size_p2, 2);
}
- memset(sst->block + len17_i, 0, (2*sst->block_size_p2 - len17_i) * sizeof(AVComplexFloat));
- apply_deemphasis(sdr, sst->block, 2*sst->block_size_p2, sample_rate_p2, + 1);
+ memset(sst->block + len17_i, 0, (2*sdr->fm_block_size_p2 - len17_i) * sizeof(AVComplexFloat));
+ apply_deemphasis(sdr, sst->block, 2*sdr->fm_block_size_p2, sample_rate_p2, + 1);
sst->ifft_p2(sst->ifft_p2_ctx, sst->iblock , sst->block, sizeof(AVComplexFloat));
- memset(sst->iblock + 2*sst->block_size_p2, 0 ,(2*sst->block_size -2*sst->block_size_p2) * sizeof(AVComplexFloat));
+ memset(sst->iblock + 2*sdr->fm_block_size_p2, 0 ,(2*sst->block_size -2*sdr->fm_block_size_p2) * sizeof(AVComplexFloat));
scale = 5 / (M_PI * 2*sst->block_size);
- for(i = 0; i<sst->block_size_p2; i++) {
+ for(i = 0; i<sdr->fm_block_size_p2; i++) {
float m, q;
m = sst->out_buf[2*i+0] + (sst->iblock[i ].re) * sst->window_p2[i ] * scale;
- newbuf[2*i+0] = (sst->iblock[i + sst->block_size_p2].re) * sst->window_p2[i + sst->block_size_p2] * scale;
+ newbuf[2*i+0] = (sst->iblock[i + sdr->fm_block_size_p2].re) * sst->window_p2[i + sdr->fm_block_size_p2] * scale;
if (carrier19_i >= 0) {
q = sst->out_buf[2*i+1] + sst->iside[i ].im * sst->window_p2[i ] * scale;
- newbuf[2*i+1] = sst->iside[i + sst->block_size_p2].im * sst->window_p2[i + sst->block_size_p2] * scale;
+ newbuf[2*i+1] = sst->iside[i + sdr->fm_block_size_p2].im * sst->window_p2[i + sdr->fm_block_size_p2] * scale;
sst->out_buf[2*i+0] = m + q;
sst->out_buf[2*i+1] = m - q;
@@ -1031,7 +1044,7 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
}
}
- ret = av_packet_from_data(pkt, (void*)sst->out_buf, sizeof(*sst->out_buf) * 2 * sst->block_size_p2);
+ ret = av_packet_from_data(pkt, (void*)sst->out_buf, sizeof(*sst->out_buf) * 2 * sdr->fm_block_size_p2);
if (ret < 0)
av_free(sst->out_buf);
sst->out_buf = newbuf;
@@ -1096,7 +1109,6 @@ static void free_stream(SDRContext *sdr, int stream_index)
av_freep(&sst->iside);
av_freep(&sst->window);
av_freep(&sst->window_p2);
- av_freep(&sst->rds_ring);
}
static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
@@ -1130,29 +1142,24 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
if (ret < 0)
return ret;
- if (sst->station->bandwidth_p2) {
+ if (sst->station->modulation == FM) {
//Allocate 2nd stage demodulation fields if needed
ret = av_tx_init(&sst-> fft_ctx, &sst-> fft, AV_TX_FLOAT_FFT, 0, 2*sst->block_size , NULL, 0);
if (ret < 0)
return ret;
- for (sst->block_size_p2 = 4; 2ll *sst->station->bandwidth_p2 * block_time > sst->block_size_p2; sst->block_size_p2 <<= 1)
- ;
- ret = av_tx_init(&sst->ifft_p2_ctx, &sst->ifft_p2, AV_TX_FLOAT_FFT, 1, 2*sst->block_size_p2, NULL, 0);
+ ret = av_tx_init(&sst->ifft_p2_ctx, &sst->ifft_p2, AV_TX_FLOAT_FFT, 1, 2*sdr->fm_block_size_p2, NULL, 0);
if (ret < 0)
return ret;
- sst->rds_ring_size = ceil((2*105 / 1187.5 + 2.0*block_time) * sst->block_size_p2 / block_time);
-
- sst->rds_ring = av_mallocz(sizeof(*sst->rds_ring ) * sst->rds_ring_size);
- sst->window_p2 = av_malloc(sizeof(*sst->window_p2)* 2 * sst->block_size_p2);
- sst->iside = av_malloc(sizeof(*sst->iside) * 2 * sst->block_size_p2);
- if (!sst->iside || !sst->window_p2 || !sst->rds_ring)
+ sst->window_p2 = av_malloc(sizeof(*sst->window_p2)* 2 * sdr->fm_block_size_p2);
+ sst->iside = av_malloc(sizeof(*sst->iside) * 2 * sdr->fm_block_size_p2);
+ if (!sst->iside || !sst->window_p2)
return AVERROR(ENOMEM);
- avpriv_kbd_window_init(sst->window_p2, sdr->kbd_alpha, sst->block_size_p2);
- for(int i = sst->block_size_p2; i < 2 * sst->block_size_p2; i++) {
- sst->window_p2[i] = sst->window_p2[2*sst->block_size_p2 - i - 1];
+ avpriv_kbd_window_init(sst->window_p2, sdr->kbd_alpha, sdr->fm_block_size_p2);
+ for(int i = sdr->fm_block_size_p2; i < 2 * sdr->fm_block_size_p2; i++) {
+ sst->window_p2[i] = sst->window_p2[2*sdr->fm_block_size_p2 - i - 1];
}
}
@@ -1491,6 +1498,11 @@ int ff_sdr_common_init(AVFormatContext *s)
}
av_log(s, AV_LOG_INFO, "Block size %d\n", sdr->block_size);
+ double block_time = sdr->block_size / (double)sdr->sdr_sample_rate;
+ sdr->fm_bandwidth_p2 = 18 * 1000;
+ if (!sdr->fm_block_size_p2)
+ for (sdr->fm_block_size_p2 = 4; 2ll *sdr->fm_bandwidth_p2 * block_time > sdr->fm_block_size_p2; sdr->fm_block_size_p2 <<= 1)
+ ;
sdr->windowed_block = av_malloc(sizeof(*sdr->windowed_block) * 2 * sdr->block_size);
sdr->block = av_malloc(sizeof(*sdr->block ) * 2 * sdr->block_size);
--
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".
^ permalink raw reply [flat|nested] 13+ messages in thread
* [FFmpeg-devel] [PATCH 05/12] avradio/rds: move phase 2 window to main context
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
` (2 preceding siblings ...)
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 04/12] avradio/sdr: Move rds_ring to Station Michael Niedermayer
@ 2023-07-11 21:19 ` Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 06/12] avradio/sdr: Warnings cleanup Michael Niedermayer
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Its the same for all FM stations and channels so we dont need more than
1
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/rds.c | 11 +++++------
libavradio/sdr.h | 4 ++--
libavradio/sdrdemux.c | 33 +++++++++++++++++----------------
3 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/libavradio/rds.c b/libavradio/rds.c
index e16685be18..1392bb0874 100644
--- a/libavradio/rds.c
+++ b/libavradio/rds.c
@@ -150,10 +150,9 @@ static int decode_rds_group(SDRContext *sdr, Station *station, uint16_t group[4]
return 0;
}
-int ff_sdr_decode_rds(SDRContext *sdr, SDRStream *sst, AVComplexFloat *signal)
+int ff_sdr_decode_rds(SDRContext *sdr, Station *station, AVComplexFloat *signal)
{
int i, phase;
- Station *station = sst->station;
float (*ring)[2] = station->rds_ring;
float diff[2*104 - 1];
uint16_t group[4];
@@ -164,10 +163,10 @@ int ff_sdr_decode_rds(SDRContext *sdr, SDRStream *sst, AVComplexFloat *signal)
//For reasons that are beyond me, RDS spec allows inphase and quadrature so we have to compute and check both
for (int i=0; i < sdr->fm_block_size_p2; i++) {
- ring[ station->rds_ring_pos + i ][0] += signal[i].re * sst->window_p2[i];
- ring[ station->rds_ring_pos + i + sdr->fm_block_size_p2 ][0] = signal[i + sdr->fm_block_size_p2].re * sst->window_p2[i + sdr->fm_block_size_p2];
- ring[ station->rds_ring_pos + i ][1] += signal[i].im * sst->window_p2[i];
- ring[ station->rds_ring_pos + i + sdr->fm_block_size_p2 ][1] = signal[i + sdr->fm_block_size_p2].im * sst->window_p2[i + sdr->fm_block_size_p2];
+ ring[ station->rds_ring_pos + i ][0] += signal[i].re * sdr->fm_window_p2[i];
+ ring[ station->rds_ring_pos + i + sdr->fm_block_size_p2 ][0] = signal[i + sdr->fm_block_size_p2].re * sdr->fm_window_p2[i + sdr->fm_block_size_p2];
+ ring[ station->rds_ring_pos + i ][1] += signal[i].im * sdr->fm_window_p2[i];
+ ring[ station->rds_ring_pos + i + sdr->fm_block_size_p2 ][1] = signal[i + sdr->fm_block_size_p2].im * sdr->fm_window_p2[i + sdr->fm_block_size_p2];
}
station->rds_ring_pos += sdr->fm_block_size_p2;
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 7d951334f9..f966a16e2e 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -113,7 +113,6 @@ typedef struct SDRStream {
AVComplexFloat *icarrier;
AVComplexFloat *iside;
float *window;
- float *window_p2;
Station *station;
float am_amplitude;
@@ -163,6 +162,7 @@ typedef struct SDRContext {
int64_t fm_bandwidth_p2;
int fm_block_size_p2;
int rds_ring_size;
+ float *fm_window_p2;
int am_mode; ///< AMMode but using int for generic option access
int emphasis_mode;
@@ -278,7 +278,7 @@ int ff_sdr_histogram_score(Station *s);
* Decode RDS
* @param signal the time domain RDS signal
*/
-int ff_sdr_decode_rds(SDRContext *sdr, SDRStream *sst, AVComplexFloat *signal);
+int ff_sdr_decode_rds(SDRContext *sdr, Station *station, AVComplexFloat *signal);
static inline float len2(AVComplexFloat c)
{
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 762328aebe..93e48c2cdf 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -1005,15 +1005,15 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
memcpy(sst->block + i, sst->block + 3*carrier19_i, sizeof(AVComplexFloat)*len2_4_i);
memcpy(sst->block + i + 2*sdr->fm_block_size_p2 - len2_4_i, sst->block + 3*carrier19_i - len2_4_i, sizeof(AVComplexFloat)*len2_4_i);
sst->ifft_p2(sst->ifft_p2_ctx, sst->iside , sst->block + i, sizeof(AVComplexFloat));
- synchronous_am_demodulationN(sst->iside, sst->icarrier, sst->window_p2, 2*sdr->fm_block_size_p2, 3);
- ff_sdr_decode_rds(sdr, sst, sst->iside);
+ synchronous_am_demodulationN(sst->iside, sst->icarrier, sdr->fm_window_p2, 2*sdr->fm_block_size_p2, 3);
+ ff_sdr_decode_rds(sdr, sst->station, sst->iside);
memcpy(sst->block + i, sst->block + 2*carrier19_i, sizeof(AVComplexFloat)*len17_i);
memcpy(sst->block + i + 2*sdr->fm_block_size_p2 - len17_i, sst->block + 2*carrier19_i - len17_i, sizeof(AVComplexFloat)*len17_i);
apply_deemphasis(sdr, sst->block + i, sdr->fm_block_size_p2, sample_rate_p2, + 1);
apply_deemphasis(sdr, sst->block + i + 2*sdr->fm_block_size_p2, sdr->fm_block_size_p2, sample_rate_p2, - 1);
sst->ifft_p2(sst->ifft_p2_ctx, sst->iside , sst->block + i, sizeof(AVComplexFloat));
- synchronous_am_demodulationN(sst->iside, sst->icarrier, sst->window_p2, 2*sdr->fm_block_size_p2, 2);
+ synchronous_am_demodulationN(sst->iside, sst->icarrier, sdr->fm_window_p2, 2*sdr->fm_block_size_p2, 2);
}
memset(sst->block + len17_i, 0, (2*sdr->fm_block_size_p2 - len17_i) * sizeof(AVComplexFloat));
apply_deemphasis(sdr, sst->block, 2*sdr->fm_block_size_p2, sample_rate_p2, + 1);
@@ -1024,12 +1024,12 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
for(i = 0; i<sdr->fm_block_size_p2; i++) {
float m, q;
- m = sst->out_buf[2*i+0] + (sst->iblock[i ].re) * sst->window_p2[i ] * scale;
- newbuf[2*i+0] = (sst->iblock[i + sdr->fm_block_size_p2].re) * sst->window_p2[i + sdr->fm_block_size_p2] * scale;
+ m = sst->out_buf[2*i+0] + (sst->iblock[i ].re) * sdr->fm_window_p2[i ] * scale;
+ newbuf[2*i+0] = (sst->iblock[i + sdr->fm_block_size_p2].re) * sdr->fm_window_p2[i + sdr->fm_block_size_p2] * scale;
if (carrier19_i >= 0) {
- q = sst->out_buf[2*i+1] + sst->iside[i ].im * sst->window_p2[i ] * scale;
- newbuf[2*i+1] = sst->iside[i + sdr->fm_block_size_p2].im * sst->window_p2[i + sdr->fm_block_size_p2] * scale;
+ q = sst->out_buf[2*i+1] + sst->iside[i ].im * sdr->fm_window_p2[i ] * scale;
+ newbuf[2*i+1] = sst->iside[i + sdr->fm_block_size_p2].im * sdr->fm_window_p2[i + sdr->fm_block_size_p2] * scale;
sst->out_buf[2*i+0] = m + q;
sst->out_buf[2*i+1] = m - q;
@@ -1108,7 +1108,6 @@ static void free_stream(SDRContext *sdr, int stream_index)
av_freep(&sst->icarrier);
av_freep(&sst->iside);
av_freep(&sst->window);
- av_freep(&sst->window_p2);
}
static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
@@ -1152,15 +1151,9 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
if (ret < 0)
return ret;
- sst->window_p2 = av_malloc(sizeof(*sst->window_p2)* 2 * sdr->fm_block_size_p2);
sst->iside = av_malloc(sizeof(*sst->iside) * 2 * sdr->fm_block_size_p2);
- if (!sst->iside || !sst->window_p2)
+ if (!sst->iside)
return AVERROR(ENOMEM);
-
- avpriv_kbd_window_init(sst->window_p2, sdr->kbd_alpha, sdr->fm_block_size_p2);
- for(int i = sdr->fm_block_size_p2; i < 2 * sdr->fm_block_size_p2; i++) {
- sst->window_p2[i] = sst->window_p2[2*sdr->fm_block_size_p2 - i - 1];
- }
}
sst->out_buf = av_mallocz(sizeof(*sst->out_buf) * 2 * sst->block_size);
@@ -1508,7 +1501,9 @@ int ff_sdr_common_init(AVFormatContext *s)
sdr->block = av_malloc(sizeof(*sdr->block ) * 2 * sdr->block_size);
sdr->len2block = av_malloc(sizeof(*sdr->len2block) * 2 * sdr->block_size);
sdr->window = av_malloc(sizeof(*sdr->window ) * 2 * sdr->block_size);
- if (!sdr->windowed_block || !sdr->len2block || !sdr->block || !sdr->window)
+ sdr->fm_window_p2 = av_malloc(sizeof(*sdr->fm_window_p2)* 2 * sdr->fm_block_size_p2);
+
+ if (!sdr->windowed_block || !sdr->len2block || !sdr->block || !sdr->window || !sdr->fm_window_p2)
return AVERROR(ENOMEM);
ret = av_tx_init(&sdr->fft_ctx, &sdr->fft, AV_TX_FLOAT_FFT, 0, 2*sdr->block_size, NULL, 0);
@@ -1523,6 +1518,11 @@ int ff_sdr_common_init(AVFormatContext *s)
for (int i = 0; i < 2 * sdr->block_size; i++)
sdr->window[i] *= ((i&1) ? 1:-1) * scale;
+ avpriv_kbd_window_init(sdr->fm_window_p2, sdr->kbd_alpha, sdr->fm_block_size_p2);
+ for(int i = sdr->fm_block_size_p2; i < 2 * sdr->fm_block_size_p2; i++) {
+ sdr->fm_window_p2[i] = sdr->fm_window_p2[2*sdr->fm_block_size_p2 - i - 1];
+ }
+
if (sdr->waterfall_st_index >= 0) {
AVStream *st = s->streams[sdr->waterfall_st_index];
SDRStream *sst = st->priv_data;
@@ -1971,6 +1971,7 @@ int ff_sdr_read_close(AVFormatContext *s)
av_freep(&sdr->block);
av_freep(&sdr->len2block);
av_freep(&sdr->window);
+ av_freep(&sdr->fm_window_p2);
av_tx_uninit(&sdr->fft_ctx);
sdr->fft = NULL;
--
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".
^ permalink raw reply [flat|nested] 13+ messages in thread
* [FFmpeg-devel] [PATCH 06/12] avradio/sdr: Warnings cleanup
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
` (3 preceding siblings ...)
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 05/12] avradio/rds: move phase 2 window to main context Michael Niedermayer
@ 2023-07-11 21:19 ` Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 07/12] avradio/rds: warnings cleanup Michael Niedermayer
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdr.h | 1 +
libavradio/sdrdemux.c | 29 ++++++++++++++---------------
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index f966a16e2e..834b1f40b4 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -152,6 +152,7 @@ typedef struct SDRContext {
int64_t last_pts;
int64_t pts;
int block_size;
+ double block_time;
int kbd_alpha;
AVComplexFloat *windowed_block;
int64_t block_center_freq; ///< center frequency the current block contains
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 93e48c2cdf..8b8c126380 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -177,14 +177,15 @@ static int create_station(SDRContext *sdr, Station *candidate_station) {
double freq = candidate_station->frequency;
int64_t bandwidth = candidate_station->bandwidth;
float score = candidate_station->score;
- void *tmp;
- int i;
+ int i, nb_stations;
Station *best_station = NULL;
float drift = bandwidth/3.0;
double best_distance = drift;
int conflict = INT_MAX;
int nb_candidate_conflict = 0;
int nb_candidate_match = 0;
+ Station *station_list[1000];
+
if (candidate_station->in_station_list)
return 0;
@@ -193,8 +194,7 @@ static int create_station(SDRContext *sdr, Station *candidate_station) {
if (ff_sdr_histogram_score(candidate_station) <= 0)
return 0;
- Station *station_list[1000];
- int nb_stations = ff_sdr_find_stations(sdr, sdr->block_center_freq, sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
+ nb_stations = ff_sdr_find_stations(sdr, sdr->block_center_freq, sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
for (i=0; i<nb_stations; i++) {
Station *s = station_list[i];
double delta = fabs(s->frequency - freq);
@@ -286,11 +286,12 @@ static int create_station(SDRContext *sdr, Station *candidate_station) {
static void create_stations(SDRContext *sdr)
{
Station *station_list[1000];
+ int nb_stations;
if (!sdr->block_center_freq)
return;
- int nb_stations = ff_sdr_find_stations(sdr, sdr->block_center_freq, sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
+ nb_stations = ff_sdr_find_stations(sdr, sdr->block_center_freq, sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
for(int i = 0; i<nb_stations; i++) {
create_station(sdr, station_list[i]);
@@ -392,7 +393,6 @@ static int create_candidate_station(SDRContext *sdr, enum Modulation modulation,
}
if (!nb_stations) {
- double block_time = sdr->block_size / (double)sdr->sdr_sample_rate;
station = av_mallocz(sizeof(*station));
if (!station)
return AVERROR(ENOMEM);
@@ -400,7 +400,7 @@ static int create_candidate_station(SDRContext *sdr, enum Modulation modulation,
if (!sdr->rds_ring_size)
- sdr->rds_ring_size = ceil((2*105 / 1187.5 + 2.0*block_time) * sdr->fm_block_size_p2 / block_time);
+ sdr->rds_ring_size = ceil((2*105 / 1187.5 + 2.0*sdr->block_time) * sdr->fm_block_size_p2 / sdr->block_time);
station->rds_ring = av_mallocz(sizeof(*station->rds_ring ) * sdr->rds_ring_size);
@@ -901,7 +901,7 @@ static int probe_fm(SDRContext *sdr)
float rmax = max_in_range(sdr, i-half_bw_i/4, i+half_bw_i/4);
int lowcount = countbelow(sdr, i-half_bw_i/4, i+half_bw_i/4, rmax / 100);
- double peak_i;
+ double peak_i, f, f2;
if (lowcount / (half_bw_i*0.5) > 0.99)
continue;
@@ -912,8 +912,8 @@ static int probe_fm(SDRContext *sdr)
if (peak_i < 0)
continue;
av_assert0(fabs(peak_i-i) < 2);
- double f = peak_i * 0.5 * sdr->sdr_sample_rate / sdr->block_size + sdr->block_center_freq - sdr->sdr_sample_rate/2;
- double f2 = center * 0.5 * sdr->sdr_sample_rate / sdr->block_size + sdr->block_center_freq - sdr->sdr_sample_rate/2;
+ f = peak_i * 0.5 * sdr->sdr_sample_rate / sdr->block_size + sdr->block_center_freq - sdr->sdr_sample_rate/2;
+ f2 = center * 0.5 * sdr->sdr_sample_rate / sdr->block_size + sdr->block_center_freq - sdr->sdr_sample_rate/2;
if (fabs(f2 - f) > 1000)
continue;
@@ -1115,7 +1115,6 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
AVFormatContext *s = sdr->avfmt;
AVStream *st = s->streams[stream_index];
SDRStream *sst = st->priv_data;
- double block_time = sdr->block_size / (double)sdr->sdr_sample_rate;
int ret;
//For now we expect each station to be only demodulated once, nothing should break though if its done more often
@@ -1133,7 +1132,7 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
free_stream(sdr, stream_index);
- for (sst->block_size = 4; 2ll *sst->station->bandwidth * block_time > sst->block_size; sst->block_size <<= 1)
+ for (sst->block_size = 4; 2ll *sst->station->bandwidth * sdr->block_time > sst->block_size; sst->block_size <<= 1)
;
sst->block_size = FFMIN(sdr->block_size, sst->block_size);
@@ -1491,10 +1490,10 @@ int ff_sdr_common_init(AVFormatContext *s)
}
av_log(s, AV_LOG_INFO, "Block size %d\n", sdr->block_size);
- double block_time = sdr->block_size / (double)sdr->sdr_sample_rate;
+ sdr->block_time = sdr->block_size / (double)sdr->sdr_sample_rate;
sdr->fm_bandwidth_p2 = 18 * 1000;
if (!sdr->fm_block_size_p2)
- for (sdr->fm_block_size_p2 = 4; 2ll *sdr->fm_bandwidth_p2 * block_time > sdr->fm_block_size_p2; sdr->fm_block_size_p2 <<= 1)
+ for (sdr->fm_block_size_p2 = 4; 2ll *sdr->fm_bandwidth_p2 * sdr->block_time > sdr->fm_block_size_p2; sdr->fm_block_size_p2 <<= 1)
;
sdr->windowed_block = av_malloc(sizeof(*sdr->windowed_block) * 2 * sdr->block_size);
@@ -1836,9 +1835,9 @@ process_next_block:
return ret;
}
} else {
- av_assert0(sdr->mode == AllStationMode);
Station *station_list[1000];
int nb_stations = ff_sdr_find_stations(sdr, sdr->block_center_freq, sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
+ av_assert0(sdr->mode == AllStationMode);
for(int i = 0; i<nb_stations; i++) {
Station *station = station_list[i];
if (!station->stream && station->in_station_list) {
--
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".
^ permalink raw reply [flat|nested] 13+ messages in thread
* [FFmpeg-devel] [PATCH 07/12] avradio/rds: warnings cleanup
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
` (4 preceding siblings ...)
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 06/12] avradio/sdr: Warnings cleanup Michael Niedermayer
@ 2023-07-11 21:19 ` Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 08/12] avradio/sdr: Move IFFT and block size to main context Michael Niedermayer
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/rds.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/libavradio/rds.c b/libavradio/rds.c
index 1392bb0874..99e5360b72 100644
--- a/libavradio/rds.c
+++ b/libavradio/rds.c
@@ -171,8 +171,10 @@ int ff_sdr_decode_rds(SDRContext *sdr, Station *station, AVComplexFloat *signal)
station->rds_ring_pos += sdr->fm_block_size_p2;
while (station->rds_ring_pos > IDX(2) + IDX(4*104-1)) {
- int best_phase;
+ int best_phase, step;
float best_amplitude = -1;
+ float last_bpsk = 0;
+ int best_errors = INT_MAX;
for (phase = 0; phase < 2*IDX(2); phase++) {
double a = 0;
for (i = 0; i<2*104; i++) {
@@ -185,7 +187,6 @@ int ff_sdr_decode_rds(SDRContext *sdr, Station *station, AVComplexFloat *signal)
}
phase = best_phase;
- float last_bpsk = 0;
for (i = 0; i<2*104; i++) {
float bpsk = ring[IDX(2*i+1)][phase] - ring[IDX(2*i)][phase];
if (i)
@@ -193,7 +194,6 @@ int ff_sdr_decode_rds(SDRContext *sdr, Station *station, AVComplexFloat *signal)
last_bpsk = bpsk;
}
- int best_errors = INT_MAX;
for (phase = 0; phase < 104; phase++) {
int error = 0;
for (int block = 0; block < 4; block++) {
@@ -217,7 +217,7 @@ int ff_sdr_decode_rds(SDRContext *sdr, Station *station, AVComplexFloat *signal)
decode_rds_group(sdr, station, group);
}
}
- int step = IDX(2*(best_phase + 103));
+ step = IDX(2*(best_phase + 103));
av_assert0(station->rds_ring_pos >= step);
memmove(ring, ring + step, (station->rds_ring_pos + sdr->fm_block_size_p2 - step) * sizeof(*station->rds_ring));
--
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".
^ permalink raw reply [flat|nested] 13+ messages in thread
* [FFmpeg-devel] [PATCH 08/12] avradio/sdr: Move IFFT and block size to main context
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
` (5 preceding siblings ...)
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 07/12] avradio/rds: warnings cleanup Michael Niedermayer
@ 2023-07-11 21:19 ` Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 09/12] avradio/sdr: Move per stream arraies " Michael Niedermayer
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
This avoids duplicating this per stream instance
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdr.h | 12 +++-
libavradio/sdrdemux.c | 144 ++++++++++++++++++++++++------------------
2 files changed, 91 insertions(+), 65 deletions(-)
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 834b1f40b4..79e48e6162 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -99,13 +99,10 @@ typedef struct FIFOElement {
} FIFOElement;
typedef struct SDRStream {
- AVTXContext *ifft_ctx;
AVTXContext *fft_ctx;
AVTXContext *ifft_p2_ctx;
- av_tx_fn ifft;
av_tx_fn fft;
av_tx_fn ifft_p2;
- int block_size;
int processing_index;
float *out_buf;
AVComplexFloat *block;
@@ -160,11 +157,20 @@ typedef struct SDRContext {
int sample_size;
double sample_scale;
+ int64_t am_bandwidth;
+ int64_t fm_bandwidth;
int64_t fm_bandwidth_p2;
+ int am_block_size;
+ int fm_block_size;
int fm_block_size_p2;
int rds_ring_size;
float *fm_window_p2;
+ AVTXContext *am_ifft_ctx;
+ AVTXContext *fm_ifft_ctx;
+ av_tx_fn am_ifft;
+ av_tx_fn fm_ifft;
+
int am_mode; ///< AMMode but using int for generic option access
int emphasis_mode;
int am_fft_ref;
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 8b8c126380..443f48aebb 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -541,7 +541,7 @@ static double find_peak_macleod(const SDRContext *sdr, const AVComplexFloat *dat
static int probe_am(SDRContext *sdr)
{
int i;
- int bandwidth_f = 6000;
+ int bandwidth_f = sdr->am_bandwidth;
int half_bw_i = bandwidth_f * (int64_t)sdr->block_size / sdr->sdr_sample_rate;
int border_i = (sdr->sdr_sample_rate - sdr->bandwidth) * sdr->block_size / sdr->sdr_sample_rate;
double avg = 0;
@@ -675,7 +675,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
int len = (bandwidth * 2ll * sdr->block_size + sdr->sdr_sample_rate/2) / sdr->sdr_sample_rate;
float *newbuf;
float scale;
- int sample_rate = sdr->sdr_sample_rate * (int64_t)sst->block_size / sdr->block_size;
+ int sample_rate = sdr->sdr_sample_rate * (int64_t)sdr->am_block_size / sdr->block_size;
int ret, i;
double current_station_i;
float limits[2] = {-0.0, 0.0};
@@ -685,7 +685,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
#define CARRIER_SEARCH 2
if (index + len + CARRIER_SEARCH>= 2*sdr->block_size ||
index - len - CARRIER_SEARCH < 0 ||
- 2*len + 1 > 2*sst->block_size)
+ 2*len + 1 > 2*sdr->am_block_size)
return AVERROR(ERANGE);
current_station_i = find_am_carrier(sdr, sdr->block, 2*sdr->block_size, sdr->len2block, index, CARRIER_SEARCH, len);
@@ -699,21 +699,21 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
am_mode = AMEnvelope;
}
- newbuf = av_malloc(sizeof(*sst->out_buf) * 2 * sst->block_size);
+ newbuf = av_malloc(sizeof(*sst->out_buf) * 2 * sdr->am_block_size);
if (!newbuf)
return AVERROR(ENOMEM);
#define SEPC 4
i = 2*len+1;
memcpy(sst->block, sdr->block + index - len, sizeof(*sst->block) * i);
- memset(sst->block + i, 0, sizeof(*sst->block) * (2 * sst->block_size - i));
+ memset(sst->block + i, 0, sizeof(*sst->block) * (2 * sdr->am_block_size - i));
- sst->ifft(sst->ifft_ctx, sst->iblock , sst->block, sizeof(AVComplexFloat));
+ sdr->am_ifft(sdr->am_ifft_ctx, sst->iblock , sst->block, sizeof(AVComplexFloat));
if (am_mode == AMEnvelope) {
double vdotw = 0;
double wdot = 0; // could be precalculated
- for (i = 0; i<2*sst->block_size; i++) {
+ for (i = 0; i<2*sdr->am_block_size; i++) {
float w = sst->window[i];
float v = sqrt(len2(sst->iblock[i]));
sst->iblock[i].re = v;
@@ -724,7 +724,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
}
vdotw /= wdot ;
- for (i = 0; i<2*sst->block_size; i++) {
+ for (i = 0; i<2*sdr->am_block_size; i++) {
float w = sst->window[i];
sst->iblock[i].re -= w*vdotw;
}
@@ -735,14 +735,14 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
memset(sst->block, 0, sizeof(*sst->block) * i);
for (i = len-SEPC+1; i<len+SEPC; i++)
sst->block[i] = sdr->block[index + i - len];
- sst->ifft(sst->ifft_ctx, sst->icarrier, sst->block, sizeof(AVComplexFloat));
+ sdr->am_ifft(sdr->am_ifft_ctx, sst->icarrier, sst->block, sizeof(AVComplexFloat));
- synchronous_am_demodulationN(sst->iblock, sst->icarrier, sst->window, 2*sst->block_size, 1);
+ synchronous_am_demodulationN(sst->iblock, sst->icarrier, sst->window, 2*sdr->am_block_size, 1);
scale = 0.9;
} else {
// Synchronous demodulation using Macleod based systhesized carrier
double fcorr = F2INDEX(freq) - index + len;
- double theta = -M_PI*fcorr / sst->block_size;
+ double theta = -M_PI*fcorr / sdr->am_block_size;
AVComplexDouble mdelta = {cos(theta), sin(theta)};
AVComplexDouble m = {1,0};
AVComplexDouble dc1 = {0,0};
@@ -751,7 +751,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
double dcw = 0;
float amp, stamp, wamp;
- for(i = 0; i<2*sst->block_size; i++) {
+ for(i = 0; i<2*sdr->am_block_size; i++) {
double tmp;
AVComplexFloat v = sst->iblock[i];
sst->iblock[i].re = v.re*m.re - v.im*m.im;
@@ -773,7 +773,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
wamp = amp/stamp;
mm = (AVComplexFloat){dc1.re * amp, -dc1.im * amp};
- for(i = 0; i<2*sst->block_size; i++) {
+ for(i = 0; i<2*sdr->am_block_size; i++) {
AVComplexFloat v = sst->iblock[i];
sst->iblock[i].re = v.re*mm.re - v.im*mm.im - sst->window[i] * wamp;
sst->iblock[i].im = v.re*mm.im + v.im*mm.re;
@@ -782,7 +782,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
scale = 0.9;
}
- for(i = 0; i<2*sst->block_size; i++) {
+ for(i = 0; i<2*sdr->am_block_size; i++) {
av_assert0(isfinite(sst->iblock[i].re));
av_assert0(isfinite(sst->iblock[i].im));
limits[0] = FFMIN(limits[0], FFMIN(sst->iblock[i].re - sst->iblock[i].im, sst->iblock[i].re + sst->iblock[i].im));
@@ -791,17 +791,17 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
av_assert1(FFMAX(limits[1], -limits[0]) >= 0);
scale = FFMIN(scale, 0.98 / FFMAX(limits[1], -limits[0]));
- for(i = 0; i<sst->block_size; i++) {
+ for(i = 0; i<sdr->am_block_size; i++) {
float m, q;
m = sst->out_buf[2*i+0] + (sst->iblock[i ].re) * sst->window[i ] * scale;
- newbuf[2*i+0] = (sst->iblock[i + sst->block_size].re) * sst->window[i + sst->block_size] * scale;
+ newbuf[2*i+0] = (sst->iblock[i + sdr->am_block_size].re) * sst->window[i + sdr->am_block_size] * scale;
switch(am_mode) {
case AMMidSide:
case AMLeftRight:
q = sst->out_buf[2*i+1] + sst->iblock[i ].im * sst->window[i ] * scale;
- newbuf[2*i+1] = sst->iblock[i + sst->block_size].im * sst->window[i + sst->block_size] * scale;
+ newbuf[2*i+1] = sst->iblock[i + sdr->am_block_size].im * sst->window[i + sdr->am_block_size] * scale;
switch(am_mode) {
case AMMidSide:
q *= 0.5;
@@ -828,7 +828,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
}
}
- ret = av_packet_from_data(pkt, (void*)sst->out_buf, sizeof(*sst->out_buf) * 2 * sst->block_size);
+ ret = av_packet_from_data(pkt, (void*)sst->out_buf, sizeof(*sst->out_buf) * 2 * sdr->am_block_size);
if (ret < 0)
av_free(sst->out_buf);
sst->out_buf = newbuf;
@@ -849,7 +849,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
static int probe_fm(SDRContext *sdr)
{
int i;
- int bandwidth_f = 180*1000;
+ int bandwidth_f = sdr->fm_bandwidth;
int half_bw_i = bandwidth_f * (int64_t)sdr->block_size / sdr->sdr_sample_rate;
float last_score[3] = {FLT_MAX, FLT_MAX, FLT_MAX};
int border_i = (sdr->sdr_sample_rate - FFMIN(sdr->bandwidth, sdr->sdr_sample_rate*7/8)) * sdr->block_size / sdr->sdr_sample_rate;
@@ -938,19 +938,21 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
{
AVStream *st = sdr->avfmt->streams[stream_index];
SDRStream *sst = st->priv_data;
- double freq = sst->station->frequency;
- int64_t bandwidth = sst->station->bandwidth;
+ Station *station = sst->station;
+
+ double freq = station->frequency;
+ int64_t bandwidth = station->bandwidth;
int index = lrint(F2INDEX(freq));
int len = (bandwidth * 2ll * sdr->block_size + sdr->sdr_sample_rate/2) / sdr->sdr_sample_rate;
float *newbuf;
float scale;
- int sample_rate = sdr->sdr_sample_rate * (int64_t)sst->block_size / sdr->block_size;
+ int sample_rate = sdr->sdr_sample_rate * (int64_t)sdr->fm_block_size / sdr->block_size;
int sample_rate_p2 = sdr->sdr_sample_rate * (int64_t)sdr->fm_block_size_p2 / sdr->block_size;
int ret, i;
float clip = 1.0;
- int carrier19_i = 2L*sst->block_size*19000 / sample_rate;
- int len17_i = 2L*sst->block_size*16500 / sample_rate;
- int len2_4_i = 2L*sst->block_size* 2400 / sample_rate;
+ int carrier19_i = 2L*sdr->fm_block_size*19000 / sample_rate;
+ int len17_i = 2L*sdr->fm_block_size*16500 / sample_rate;
+ int len2_4_i = 2L*sdr->fm_block_size* 2400 / sample_rate;
double carrier19_i_exact;
int W= 5;
@@ -961,21 +963,21 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
if (index + len >= 2*sdr->block_size ||
index - len < 0 ||
- 2*len + 1 > 2*sst->block_size)
+ 2*len + 1 > 2*sdr->fm_block_size)
return AVERROR(ERANGE);
- newbuf = av_malloc(sizeof(*sst->out_buf) * 2 * sst->block_size);
+ newbuf = av_malloc(sizeof(*sst->out_buf) * 2 * sdr->fm_block_size);
if (!newbuf)
return AVERROR(ENOMEM);
i = 2*len+1;
memcpy(sst->block, sdr->block + index, sizeof(*sst->block) * (len + 1));
- memcpy(sst->block + 2 * sst->block_size - len, sdr->block + index - len, sizeof(*sst->block) * len);
- memset(sst->block + len + 1, 0, sizeof(*sst->block) * (2 * sst->block_size - i));
+ memcpy(sst->block + 2 * sdr->fm_block_size - len, sdr->block + index - len, sizeof(*sst->block) * len);
+ memset(sst->block + len + 1, 0, sizeof(*sst->block) * (2 * sdr->fm_block_size - i));
- sst->ifft(sst->ifft_ctx, sst->iblock, sst->block, sizeof(AVComplexFloat));
+ sdr->fm_ifft(sdr->fm_ifft_ctx, sst->iblock, sst->block, sizeof(AVComplexFloat));
- for (i = 0; i<2*sst->block_size - 1; i++) {
+ for (i = 0; i<2*sdr->fm_block_size - 1; i++) {
AVComplexFloat x = sst->iblock[i];
AVComplexFloat y = sst->iblock[i+1];
sst->iblock[i].re = atan2(x.im * y.re - x.re * y.im,
@@ -985,18 +987,18 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
sst->iblock[i].re = 0;
sst->iblock[i].im = 0;
- av_assert0(sdr->fm_block_size_p2 * 2 < sst->block_size);
+ av_assert0(sdr->fm_block_size_p2 * 2 < sdr->fm_block_size);
//FIXME this only needs to be a RDFT
//CONSIDER, this and in fact alot can be done with bandpass and lowpass filters instead of FFTs, find out which is better
//CONSIDER synthesizing the carrier instead of IFFT, we have all parameters for that
sst->fft(sst->fft_ctx, sst->block, sst->iblock, sizeof(AVComplexFloat));
// Only the low N/2+1 are used the upper is just a reflection
- carrier19_i_exact = find_am_carrier(sdr, sst->block, 2*sst->block_size, (void*)(sst->block + 1 + sst->block_size), carrier19_i, 10, 10);
+ carrier19_i_exact = find_am_carrier(sdr, sst->block, 2*sdr->fm_block_size, (void*)(sst->block + 1 + sdr->fm_block_size), carrier19_i, 10, 10);
carrier19_i = lrint(carrier19_i_exact);
if (carrier19_i >= 0) {
- i = sst->block_size;
+ i = sdr->fm_block_size;
memset(sst->block + i, 0, 2*sdr->fm_block_size_p2 * sizeof(AVComplexFloat));
memcpy(sst->block + i, sst->block + carrier19_i, sizeof(AVComplexFloat)*(W+1));
memcpy(sst->block + i + 2*sdr->fm_block_size_p2 - W, sst->block + carrier19_i - W, sizeof(AVComplexFloat)*W);
@@ -1018,9 +1020,9 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
memset(sst->block + len17_i, 0, (2*sdr->fm_block_size_p2 - len17_i) * sizeof(AVComplexFloat));
apply_deemphasis(sdr, sst->block, 2*sdr->fm_block_size_p2, sample_rate_p2, + 1);
sst->ifft_p2(sst->ifft_p2_ctx, sst->iblock , sst->block, sizeof(AVComplexFloat));
- memset(sst->iblock + 2*sdr->fm_block_size_p2, 0 ,(2*sst->block_size -2*sdr->fm_block_size_p2) * sizeof(AVComplexFloat));
+ memset(sst->iblock + 2*sdr->fm_block_size_p2, 0 ,(2*sdr->fm_block_size -2*sdr->fm_block_size_p2) * sizeof(AVComplexFloat));
- scale = 5 / (M_PI * 2*sst->block_size);
+ scale = 5 / (M_PI * 2*sdr->fm_block_size);
for(i = 0; i<sdr->fm_block_size_p2; i++) {
float m, q;
@@ -1094,13 +1096,10 @@ static void free_stream(SDRContext *sdr, int stream_index)
AVStream *st = s->streams[stream_index];
SDRStream *sst = st->priv_data;
- av_tx_uninit(&sst->ifft_ctx);
av_tx_uninit(&sst->fft_ctx);
av_tx_uninit(&sst->ifft_p2_ctx);
- sst->ifft = NULL;
sst->fft = NULL;
sst->ifft_p2 = NULL;
- sst->block_size = 0;
av_freep(&sst->out_buf);
av_freep(&sst->block);
@@ -1110,6 +1109,16 @@ static void free_stream(SDRContext *sdr, int stream_index)
av_freep(&sst->window);
}
+static int find_block_size(SDRContext *sdr, int64_t bandwidth)
+{
+ int block_size;
+
+ for (block_size = 4; 2ll * bandwidth * sdr->block_time > block_size; block_size <<= 1)
+ ;
+
+ return FFMIN(sdr->block_size, block_size);
+}
+
static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
{
AVFormatContext *s = sdr->avfmt;
@@ -1132,17 +1141,10 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
free_stream(sdr, stream_index);
- for (sst->block_size = 4; 2ll *sst->station->bandwidth * sdr->block_time > sst->block_size; sst->block_size <<= 1)
- ;
- sst->block_size = FFMIN(sdr->block_size, sst->block_size);
-
- ret = av_tx_init(&sst->ifft_ctx, &sst->ifft, AV_TX_FLOAT_FFT, 1, 2*sst->block_size, NULL, 0);
- if (ret < 0)
- return ret;
-
+ int block_size;
if (sst->station->modulation == FM) {
//Allocate 2nd stage demodulation fields if needed
- ret = av_tx_init(&sst-> fft_ctx, &sst-> fft, AV_TX_FLOAT_FFT, 0, 2*sst->block_size , NULL, 0);
+ ret = av_tx_init(&sst-> fft_ctx, &sst-> fft, AV_TX_FLOAT_FFT, 0, 2*sdr->fm_block_size , NULL, 0);
if (ret < 0)
return ret;
@@ -1153,19 +1155,21 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
sst->iside = av_malloc(sizeof(*sst->iside) * 2 * sdr->fm_block_size_p2);
if (!sst->iside)
return AVERROR(ENOMEM);
- }
-
- sst->out_buf = av_mallocz(sizeof(*sst->out_buf) * 2 * sst->block_size);
- sst->block = av_malloc(sizeof(*sst-> block) * 2 * sst->block_size);
- sst->iblock = av_malloc(sizeof(*sst->iblock) * 2 * sst->block_size);
- sst->icarrier = av_malloc(sizeof(*sst->icarrier) * 2 * sst->block_size);
- sst->window = av_malloc(sizeof(*sst->window) * 2 * sst->block_size);
+ block_size = sdr->fm_block_size;
+ } else
+ block_size = sdr->am_block_size;
+
+ sst->out_buf = av_mallocz(sizeof(*sst->out_buf) * 2 * block_size);
+ sst->block = av_malloc(sizeof(*sst-> block) * 2 * block_size);
+ sst->iblock = av_malloc(sizeof(*sst->iblock) * 2 * block_size);
+ sst->icarrier = av_malloc(sizeof(*sst->icarrier) * 2 * block_size);
+ sst->window = av_malloc(sizeof(*sst->window) * 2 * block_size);
if (!sst->out_buf || !sst->block || !sst->iblock || !sst->icarrier || !sst->window)
return AVERROR(ENOMEM);
- avpriv_kbd_window_init(sst->window, sdr->kbd_alpha, sst->block_size);
- for(int i = sst->block_size; i < 2 * sst->block_size; i++) {
- sst->window[i] = sst->window[2*sst->block_size - i - 1];
+ avpriv_kbd_window_init(sst->window, sdr->kbd_alpha, block_size);
+ for(int i = block_size; i < 2 * block_size; i++) {
+ sst->window[i] = sst->window[2*block_size - i - 1];
}
sst->am_amplitude = 0;
@@ -1491,10 +1495,13 @@ int ff_sdr_common_init(AVFormatContext *s)
av_log(s, AV_LOG_INFO, "Block size %d\n", sdr->block_size);
sdr->block_time = sdr->block_size / (double)sdr->sdr_sample_rate;
- sdr->fm_bandwidth_p2 = 18 * 1000;
- if (!sdr->fm_block_size_p2)
- for (sdr->fm_block_size_p2 = 4; 2ll *sdr->fm_bandwidth_p2 * sdr->block_time > sdr->fm_block_size_p2; sdr->fm_block_size_p2 <<= 1)
- ;
+ sdr->am_bandwidth = 6 * 1000;
+ sdr->fm_bandwidth = 180 * 1000;
+ sdr->fm_bandwidth_p2 = 18 * 1000;
+
+ sdr->am_block_size = find_block_size(sdr, sdr->am_bandwidth);
+ sdr->fm_block_size = find_block_size(sdr, sdr->fm_bandwidth);
+ sdr->fm_block_size_p2 = find_block_size(sdr, sdr->fm_bandwidth_p2);
sdr->windowed_block = av_malloc(sizeof(*sdr->windowed_block) * 2 * sdr->block_size);
sdr->block = av_malloc(sizeof(*sdr->block ) * 2 * sdr->block_size);
@@ -1509,6 +1516,15 @@ int ff_sdr_common_init(AVFormatContext *s)
if (ret < 0)
return ret;
+ ret = av_tx_init(&sdr->am_ifft_ctx, &sdr->am_ifft, AV_TX_FLOAT_FFT, 1, 2*sdr->am_block_size, NULL, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = av_tx_init(&sdr->fm_ifft_ctx, &sdr->fm_ifft, AV_TX_FLOAT_FFT, 1, 2*sdr->fm_block_size, NULL, 0);
+ if (ret < 0)
+ return ret;
+
+
avpriv_kbd_window_init(sdr->window, sdr->kbd_alpha, sdr->block_size);
for(int i = sdr->block_size; i < 2 * sdr->block_size; i++) {
@@ -1973,7 +1989,11 @@ int ff_sdr_read_close(AVFormatContext *s)
av_freep(&sdr->fm_window_p2);
av_tx_uninit(&sdr->fft_ctx);
+ av_tx_uninit(&sdr->am_ifft_ctx);
+ av_tx_uninit(&sdr->fm_ifft_ctx);
sdr->fft = NULL;
+ sdr->am_ifft = NULL;
+ sdr->fm_ifft = NULL;
avio_close(sdr->dump_avio);
--
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".
^ permalink raw reply [flat|nested] 13+ messages in thread
* [FFmpeg-devel] [PATCH 09/12] avradio/sdr: Move per stream arraies to main context
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
` (6 preceding siblings ...)
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 08/12] avradio/sdr: Move IFFT and block size to main context Michael Niedermayer
@ 2023-07-11 21:19 ` Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 10/12] avradio/sdr: Move tx contexts out of stream so its not duplicated Michael Niedermayer
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
This avoids allocating them per stream instance
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdr.h | 15 ++--
libavradio/sdrdemux.c | 204 ++++++++++++++++++++++--------------------
2 files changed, 116 insertions(+), 103 deletions(-)
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 79e48e6162..8d7ab803d4 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -105,11 +105,7 @@ typedef struct SDRStream {
av_tx_fn ifft_p2;
int processing_index;
float *out_buf;
- AVComplexFloat *block;
- AVComplexFloat *iblock;
- AVComplexFloat *icarrier;
- AVComplexFloat *iside;
- float *window;
+
Station *station;
float am_amplitude;
@@ -164,6 +160,15 @@ typedef struct SDRContext {
int fm_block_size;
int fm_block_size_p2;
int rds_ring_size;
+ AVComplexFloat *am_block;
+ AVComplexFloat *am_iblock;
+ AVComplexFloat *am_icarrier;
+ float *am_window;
+ AVComplexFloat *fm_iside;
+ AVComplexFloat *fm_block;
+ AVComplexFloat *fm_iblock;
+ AVComplexFloat *fm_icarrier;
+ float *fm_window;
float *fm_window_p2;
AVTXContext *am_ifft_ctx;
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 443f48aebb..6442d251f6 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -705,19 +705,19 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
#define SEPC 4
i = 2*len+1;
- memcpy(sst->block, sdr->block + index - len, sizeof(*sst->block) * i);
- memset(sst->block + i, 0, sizeof(*sst->block) * (2 * sdr->am_block_size - i));
+ memcpy(sdr->am_block, sdr->block + index - len, sizeof(*sdr->am_block) * i);
+ memset(sdr->am_block + i, 0, sizeof(*sdr->am_block) * (2 * sdr->am_block_size - i));
- sdr->am_ifft(sdr->am_ifft_ctx, sst->iblock , sst->block, sizeof(AVComplexFloat));
+ sdr->am_ifft(sdr->am_ifft_ctx, sdr->am_iblock , sdr->am_block, sizeof(AVComplexFloat));
if (am_mode == AMEnvelope) {
double vdotw = 0;
double wdot = 0; // could be precalculated
for (i = 0; i<2*sdr->am_block_size; i++) {
- float w = sst->window[i];
- float v = sqrt(len2(sst->iblock[i]));
- sst->iblock[i].re = v;
- sst->iblock[i].im = 0;
+ float w = sdr->am_window[i];
+ float v = sqrt(len2(sdr->am_iblock[i]));
+ sdr->am_iblock[i].re = v;
+ sdr->am_iblock[i].im = 0;
vdotw += w*v;
wdot += w*w;
@@ -725,19 +725,19 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
vdotw /= wdot ;
for (i = 0; i<2*sdr->am_block_size; i++) {
- float w = sst->window[i];
- sst->iblock[i].re -= w*vdotw;
+ float w = sdr->am_window[i];
+ sdr->am_iblock[i].re -= w*vdotw;
}
scale = 0.9/vdotw;
} else if (sdr->am_fft_ref) {
// Synchronous demodulation using FFT
- memset(sst->block, 0, sizeof(*sst->block) * i);
+ memset(sdr->am_block, 0, sizeof(*sdr->am_block) * i);
for (i = len-SEPC+1; i<len+SEPC; i++)
- sst->block[i] = sdr->block[index + i - len];
- sdr->am_ifft(sdr->am_ifft_ctx, sst->icarrier, sst->block, sizeof(AVComplexFloat));
+ sdr->am_block[i] = sdr->block[index + i - len];
+ sdr->am_ifft(sdr->am_ifft_ctx, sdr->am_icarrier, sdr->am_block, sizeof(AVComplexFloat));
- synchronous_am_demodulationN(sst->iblock, sst->icarrier, sst->window, 2*sdr->am_block_size, 1);
+ synchronous_am_demodulationN(sdr->am_iblock, sdr->am_icarrier, sdr->am_window, 2*sdr->am_block_size, 1);
scale = 0.9;
} else {
// Synchronous demodulation using Macleod based systhesized carrier
@@ -753,16 +753,16 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
for(i = 0; i<2*sdr->am_block_size; i++) {
double tmp;
- AVComplexFloat v = sst->iblock[i];
- sst->iblock[i].re = v.re*m.re - v.im*m.im;
- sst->iblock[i].im = v.re*m.im + v.im*m.re;
+ AVComplexFloat v = sdr->am_iblock[i];
+ sdr->am_iblock[i].re = v.re*m.re - v.im*m.im;
+ sdr->am_iblock[i].im = v.re*m.im + v.im*m.re;
tmp = m.re*mdelta.im + m.im*mdelta.re;
m.re = m.re*mdelta.re - m.im*mdelta.im;
m.im = tmp;
- dc1.re += sst->iblock[i].re * sst->window[i];
- dc1.im += sst->iblock[i].im * sst->window[i];
- s2 += len2(sst->iblock[i]);
- dcw += sst->window[i] * sst->window[i];
+ dc1.re += sdr->am_iblock[i].re * sdr->am_window[i];
+ dc1.im += sdr->am_iblock[i].im * sdr->am_window[i];
+ s2 += len2(sdr->am_iblock[i]);
+ dcw += sdr->am_window[i] * sdr->am_window[i];
}
stamp = dcw / (dc1.re*dc1.re + dc1.im*dc1.im);
@@ -774,19 +774,19 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
mm = (AVComplexFloat){dc1.re * amp, -dc1.im * amp};
for(i = 0; i<2*sdr->am_block_size; i++) {
- AVComplexFloat v = sst->iblock[i];
- sst->iblock[i].re = v.re*mm.re - v.im*mm.im - sst->window[i] * wamp;
- sst->iblock[i].im = v.re*mm.im + v.im*mm.re;
+ AVComplexFloat v = sdr->am_iblock[i];
+ sdr->am_iblock[i].re = v.re*mm.re - v.im*mm.im - sdr->am_window[i] * wamp;
+ sdr->am_iblock[i].im = v.re*mm.im + v.im*mm.re;
}
scale = 0.9;
}
for(i = 0; i<2*sdr->am_block_size; i++) {
- av_assert0(isfinite(sst->iblock[i].re));
- av_assert0(isfinite(sst->iblock[i].im));
- limits[0] = FFMIN(limits[0], FFMIN(sst->iblock[i].re - sst->iblock[i].im, sst->iblock[i].re + sst->iblock[i].im));
- limits[1] = FFMAX(limits[1], FFMAX(sst->iblock[i].re - sst->iblock[i].im, sst->iblock[i].re + sst->iblock[i].im));
+ av_assert0(isfinite(sdr->am_iblock[i].re));
+ av_assert0(isfinite(sdr->am_iblock[i].im));
+ limits[0] = FFMIN(limits[0], FFMIN(sdr->am_iblock[i].re - sdr->am_iblock[i].im, sdr->am_iblock[i].re + sdr->am_iblock[i].im));
+ limits[1] = FFMAX(limits[1], FFMAX(sdr->am_iblock[i].re - sdr->am_iblock[i].im, sdr->am_iblock[i].re + sdr->am_iblock[i].im));
}
av_assert1(FFMAX(limits[1], -limits[0]) >= 0);
scale = FFMIN(scale, 0.98 / FFMAX(limits[1], -limits[0]));
@@ -794,14 +794,14 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
for(i = 0; i<sdr->am_block_size; i++) {
float m, q;
- m = sst->out_buf[2*i+0] + (sst->iblock[i ].re) * sst->window[i ] * scale;
- newbuf[2*i+0] = (sst->iblock[i + sdr->am_block_size].re) * sst->window[i + sdr->am_block_size] * scale;
+ m = sst->out_buf[2*i+0] + (sdr->am_iblock[i ].re) * sdr->am_window[i ] * scale;
+ newbuf[2*i+0] = (sdr->am_iblock[i + sdr->am_block_size].re) * sdr->am_window[i + sdr->am_block_size] * scale;
switch(am_mode) {
case AMMidSide:
case AMLeftRight:
- q = sst->out_buf[2*i+1] + sst->iblock[i ].im * sst->window[i ] * scale;
- newbuf[2*i+1] = sst->iblock[i + sdr->am_block_size].im * sst->window[i + sdr->am_block_size] * scale;
+ q = sst->out_buf[2*i+1] + sdr->am_iblock[i ].im * sdr->am_window[i ] * scale;
+ newbuf[2*i+1] = sdr->am_iblock[i + sdr->am_block_size].im * sdr->am_window[i + sdr->am_block_size] * scale;
switch(am_mode) {
case AMMidSide:
q *= 0.5;
@@ -971,67 +971,67 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
return AVERROR(ENOMEM);
i = 2*len+1;
- memcpy(sst->block, sdr->block + index, sizeof(*sst->block) * (len + 1));
- memcpy(sst->block + 2 * sdr->fm_block_size - len, sdr->block + index - len, sizeof(*sst->block) * len);
- memset(sst->block + len + 1, 0, sizeof(*sst->block) * (2 * sdr->fm_block_size - i));
+ memcpy(sdr->fm_block, sdr->block + index, sizeof(*sdr->fm_block) * (len + 1));
+ memcpy(sdr->fm_block + 2 * sdr->fm_block_size - len, sdr->block + index - len, sizeof(*sdr->fm_block) * len);
+ memset(sdr->fm_block + len + 1, 0, sizeof(*sdr->fm_block) * (2 * sdr->fm_block_size - i));
- sdr->fm_ifft(sdr->fm_ifft_ctx, sst->iblock, sst->block, sizeof(AVComplexFloat));
+ sdr->fm_ifft(sdr->fm_ifft_ctx, sdr->fm_iblock, sdr->fm_block, sizeof(AVComplexFloat));
for (i = 0; i<2*sdr->fm_block_size - 1; i++) {
- AVComplexFloat x = sst->iblock[i];
- AVComplexFloat y = sst->iblock[i+1];
- sst->iblock[i].re = atan2(x.im * y.re - x.re * y.im,
- x.re * y.re + x.im * y.im) * sst->window[i];
- sst->iblock[i].im = 0;
+ AVComplexFloat x = sdr->fm_iblock[i];
+ AVComplexFloat y = sdr->fm_iblock[i+1];
+ sdr->fm_iblock[i].re = atan2(x.im * y.re - x.re * y.im,
+ x.re * y.re + x.im * y.im) * sdr->fm_window[i];
+ sdr->fm_iblock[i].im = 0;
}
- sst->iblock[i].re = 0;
- sst->iblock[i].im = 0;
+ sdr->fm_iblock[i].re = 0;
+ sdr->fm_iblock[i].im = 0;
av_assert0(sdr->fm_block_size_p2 * 2 < sdr->fm_block_size);
//FIXME this only needs to be a RDFT
//CONSIDER, this and in fact alot can be done with bandpass and lowpass filters instead of FFTs, find out which is better
//CONSIDER synthesizing the carrier instead of IFFT, we have all parameters for that
- sst->fft(sst->fft_ctx, sst->block, sst->iblock, sizeof(AVComplexFloat));
+ sst->fft(sst->fft_ctx, sdr->fm_block, sdr->fm_iblock, sizeof(AVComplexFloat));
// Only the low N/2+1 are used the upper is just a reflection
- carrier19_i_exact = find_am_carrier(sdr, sst->block, 2*sdr->fm_block_size, (void*)(sst->block + 1 + sdr->fm_block_size), carrier19_i, 10, 10);
+ carrier19_i_exact = find_am_carrier(sdr, sdr->fm_block, 2*sdr->fm_block_size, (void*)(sdr->fm_block + 1 + sdr->fm_block_size), carrier19_i, 10, 10);
carrier19_i = lrint(carrier19_i_exact);
if (carrier19_i >= 0) {
i = sdr->fm_block_size;
- memset(sst->block + i, 0, 2*sdr->fm_block_size_p2 * sizeof(AVComplexFloat));
- memcpy(sst->block + i, sst->block + carrier19_i, sizeof(AVComplexFloat)*(W+1));
- memcpy(sst->block + i + 2*sdr->fm_block_size_p2 - W, sst->block + carrier19_i - W, sizeof(AVComplexFloat)*W);
- sst->ifft_p2(sst->ifft_p2_ctx, sst->icarrier, sst->block + i, sizeof(AVComplexFloat));
-
- memcpy(sst->block + i, sst->block + 3*carrier19_i, sizeof(AVComplexFloat)*len2_4_i);
- memcpy(sst->block + i + 2*sdr->fm_block_size_p2 - len2_4_i, sst->block + 3*carrier19_i - len2_4_i, sizeof(AVComplexFloat)*len2_4_i);
- sst->ifft_p2(sst->ifft_p2_ctx, sst->iside , sst->block + i, sizeof(AVComplexFloat));
- synchronous_am_demodulationN(sst->iside, sst->icarrier, sdr->fm_window_p2, 2*sdr->fm_block_size_p2, 3);
- ff_sdr_decode_rds(sdr, sst->station, sst->iside);
-
- memcpy(sst->block + i, sst->block + 2*carrier19_i, sizeof(AVComplexFloat)*len17_i);
- memcpy(sst->block + i + 2*sdr->fm_block_size_p2 - len17_i, sst->block + 2*carrier19_i - len17_i, sizeof(AVComplexFloat)*len17_i);
- apply_deemphasis(sdr, sst->block + i, sdr->fm_block_size_p2, sample_rate_p2, + 1);
- apply_deemphasis(sdr, sst->block + i + 2*sdr->fm_block_size_p2, sdr->fm_block_size_p2, sample_rate_p2, - 1);
- sst->ifft_p2(sst->ifft_p2_ctx, sst->iside , sst->block + i, sizeof(AVComplexFloat));
- synchronous_am_demodulationN(sst->iside, sst->icarrier, sdr->fm_window_p2, 2*sdr->fm_block_size_p2, 2);
+ memset(sdr->fm_block + i, 0, 2*sdr->fm_block_size_p2 * sizeof(AVComplexFloat));
+ memcpy(sdr->fm_block + i, sdr->fm_block + carrier19_i, sizeof(AVComplexFloat)*(W+1));
+ memcpy(sdr->fm_block + i + 2*sdr->fm_block_size_p2 - W, sdr->fm_block + carrier19_i - W, sizeof(AVComplexFloat)*W);
+ sst->ifft_p2(sst->ifft_p2_ctx, sdr->fm_icarrier, sdr->fm_block + i, sizeof(AVComplexFloat));
+
+ memcpy(sdr->fm_block + i, sdr->fm_block + 3*carrier19_i, sizeof(AVComplexFloat)*len2_4_i);
+ memcpy(sdr->fm_block + i + 2*sdr->fm_block_size_p2 - len2_4_i, sdr->fm_block + 3*carrier19_i - len2_4_i, sizeof(AVComplexFloat)*len2_4_i);
+ sst->ifft_p2(sst->ifft_p2_ctx, sdr->fm_iside , sdr->fm_block + i, sizeof(AVComplexFloat));
+ synchronous_am_demodulationN(sdr->fm_iside, sdr->fm_icarrier, sdr->fm_window_p2, 2*sdr->fm_block_size_p2, 3);
+ ff_sdr_decode_rds(sdr, sst->station, sdr->fm_iside);
+
+ memcpy(sdr->fm_block + i, sdr->fm_block + 2*carrier19_i, sizeof(AVComplexFloat)*len17_i);
+ memcpy(sdr->fm_block + i + 2*sdr->fm_block_size_p2 - len17_i, sdr->fm_block + 2*carrier19_i - len17_i, sizeof(AVComplexFloat)*len17_i);
+ apply_deemphasis(sdr, sdr->fm_block + i, sdr->fm_block_size_p2, sample_rate_p2, + 1);
+ apply_deemphasis(sdr, sdr->fm_block + i + 2*sdr->fm_block_size_p2, sdr->fm_block_size_p2, sample_rate_p2, - 1);
+ sst->ifft_p2(sst->ifft_p2_ctx, sdr->fm_iside , sdr->fm_block + i, sizeof(AVComplexFloat));
+ synchronous_am_demodulationN(sdr->fm_iside, sdr->fm_icarrier, sdr->fm_window_p2, 2*sdr->fm_block_size_p2, 2);
}
- memset(sst->block + len17_i, 0, (2*sdr->fm_block_size_p2 - len17_i) * sizeof(AVComplexFloat));
- apply_deemphasis(sdr, sst->block, 2*sdr->fm_block_size_p2, sample_rate_p2, + 1);
- sst->ifft_p2(sst->ifft_p2_ctx, sst->iblock , sst->block, sizeof(AVComplexFloat));
- memset(sst->iblock + 2*sdr->fm_block_size_p2, 0 ,(2*sdr->fm_block_size -2*sdr->fm_block_size_p2) * sizeof(AVComplexFloat));
+ memset(sdr->fm_block + len17_i, 0, (2*sdr->fm_block_size_p2 - len17_i) * sizeof(AVComplexFloat));
+ apply_deemphasis(sdr, sdr->fm_block, 2*sdr->fm_block_size_p2, sample_rate_p2, + 1);
+ sst->ifft_p2(sst->ifft_p2_ctx, sdr->fm_iblock , sdr->fm_block, sizeof(AVComplexFloat));
+ memset(sdr->fm_iblock + 2*sdr->fm_block_size_p2, 0 ,(2*sdr->fm_block_size -2*sdr->fm_block_size_p2) * sizeof(AVComplexFloat));
scale = 5 / (M_PI * 2*sdr->fm_block_size);
for(i = 0; i<sdr->fm_block_size_p2; i++) {
float m, q;
- m = sst->out_buf[2*i+0] + (sst->iblock[i ].re) * sdr->fm_window_p2[i ] * scale;
- newbuf[2*i+0] = (sst->iblock[i + sdr->fm_block_size_p2].re) * sdr->fm_window_p2[i + sdr->fm_block_size_p2] * scale;
+ m = sst->out_buf[2*i+0] + (sdr->fm_iblock[i ].re) * sdr->fm_window_p2[i ] * scale;
+ newbuf[2*i+0] = (sdr->fm_iblock[i + sdr->fm_block_size_p2].re) * sdr->fm_window_p2[i + sdr->fm_block_size_p2] * scale;
if (carrier19_i >= 0) {
- q = sst->out_buf[2*i+1] + sst->iside[i ].im * sdr->fm_window_p2[i ] * scale;
- newbuf[2*i+1] = sst->iside[i + sdr->fm_block_size_p2].im * sdr->fm_window_p2[i + sdr->fm_block_size_p2] * scale;
+ q = sst->out_buf[2*i+1] + sdr->fm_iside[i ].im * sdr->fm_window_p2[i ] * scale;
+ newbuf[2*i+1] = sdr->fm_iside[i + sdr->fm_block_size_p2].im * sdr->fm_window_p2[i + sdr->fm_block_size_p2] * scale;
sst->out_buf[2*i+0] = m + q;
sst->out_buf[2*i+1] = m - q;
@@ -1102,11 +1102,6 @@ static void free_stream(SDRContext *sdr, int stream_index)
sst->ifft_p2 = NULL;
av_freep(&sst->out_buf);
- av_freep(&sst->block);
- av_freep(&sst->iblock);
- av_freep(&sst->icarrier);
- av_freep(&sst->iside);
- av_freep(&sst->window);
}
static int find_block_size(SDRContext *sdr, int64_t bandwidth)
@@ -1152,26 +1147,14 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
if (ret < 0)
return ret;
- sst->iside = av_malloc(sizeof(*sst->iside) * 2 * sdr->fm_block_size_p2);
- if (!sst->iside)
- return AVERROR(ENOMEM);
block_size = sdr->fm_block_size;
} else
block_size = sdr->am_block_size;
sst->out_buf = av_mallocz(sizeof(*sst->out_buf) * 2 * block_size);
- sst->block = av_malloc(sizeof(*sst-> block) * 2 * block_size);
- sst->iblock = av_malloc(sizeof(*sst->iblock) * 2 * block_size);
- sst->icarrier = av_malloc(sizeof(*sst->icarrier) * 2 * block_size);
- sst->window = av_malloc(sizeof(*sst->window) * 2 * block_size);
- if (!sst->out_buf || !sst->block || !sst->iblock || !sst->icarrier || !sst->window)
+ if (!sst->out_buf)
return AVERROR(ENOMEM);
- avpriv_kbd_window_init(sst->window, sdr->kbd_alpha, block_size);
- for(int i = block_size; i < 2 * block_size; i++) {
- sst->window[i] = sst->window[2*block_size - i - 1];
- }
-
sst->am_amplitude = 0;
}
@@ -1430,6 +1413,14 @@ static void *soapy_needs_bigger_buffers_worker(SDRContext *sdr)
return NULL;
}
+static void init_window(SDRContext *sdr, float *window, int block_size)
+{
+ avpriv_kbd_window_init(window, sdr->kbd_alpha, block_size);
+ for(int i = block_size; i < 2 * block_size; i++) {
+ window[i] = window[2 * block_size - i - 1];
+ }
+}
+
int ff_sdr_common_init(AVFormatContext *s)
{
SDRContext *sdr = s->priv_data;
@@ -1507,9 +1498,21 @@ int ff_sdr_common_init(AVFormatContext *s)
sdr->block = av_malloc(sizeof(*sdr->block ) * 2 * sdr->block_size);
sdr->len2block = av_malloc(sizeof(*sdr->len2block) * 2 * sdr->block_size);
sdr->window = av_malloc(sizeof(*sdr->window ) * 2 * sdr->block_size);
+ sdr->am_block = av_malloc(sizeof(*sdr->am_block) * 2 * sdr->am_block_size);
+ sdr->am_iblock = av_malloc(sizeof(*sdr->am_iblock) * 2 * sdr->am_block_size);
+ sdr->am_icarrier = av_malloc(sizeof(*sdr->am_icarrier) * 2 * sdr->am_block_size);
+ sdr->am_window = av_malloc(sizeof(*sdr->am_window) * 2 * sdr->am_block_size);
sdr->fm_window_p2 = av_malloc(sizeof(*sdr->fm_window_p2)* 2 * sdr->fm_block_size_p2);
-
- if (!sdr->windowed_block || !sdr->len2block || !sdr->block || !sdr->window || !sdr->fm_window_p2)
+ sdr->fm_iside = av_malloc(sizeof(*sdr->fm_iside) * 2 * sdr->fm_block_size_p2);
+ sdr->fm_block = av_malloc(sizeof(*sdr->fm_block) * 2 * sdr->fm_block_size);
+ sdr->fm_iblock = av_malloc(sizeof(*sdr->fm_iblock) * 2 * sdr->fm_block_size);
+ sdr->fm_icarrier = av_malloc(sizeof(*sdr->fm_icarrier) * 2 * sdr->fm_block_size);
+ sdr->fm_window = av_malloc(sizeof(*sdr->fm_window) * 2 * sdr->fm_block_size);
+
+ if (!sdr->windowed_block || !sdr->len2block || !sdr->block || !sdr->window || !sdr->fm_window_p2 || !sdr->fm_iside ||
+ !sdr->am_block || !sdr->am_iblock || !sdr->am_icarrier || !sdr->am_window || !sdr->fm_window_p2 || !sdr->fm_iside ||
+ !sdr->fm_block || !sdr->fm_iblock || !sdr->fm_icarrier || !sdr->fm_window
+ )
return AVERROR(ENOMEM);
ret = av_tx_init(&sdr->fft_ctx, &sdr->fft, AV_TX_FLOAT_FFT, 0, 2*sdr->block_size, NULL, 0);
@@ -1524,19 +1527,14 @@ int ff_sdr_common_init(AVFormatContext *s)
if (ret < 0)
return ret;
+ init_window(sdr, sdr->window, sdr->block_size);
- avpriv_kbd_window_init(sdr->window, sdr->kbd_alpha, sdr->block_size);
-
- for(int i = sdr->block_size; i < 2 * sdr->block_size; i++) {
- sdr->window[i] = sdr->window[2*sdr->block_size - i - 1];
- }
for (int i = 0; i < 2 * sdr->block_size; i++)
sdr->window[i] *= ((i&1) ? 1:-1) * scale;
- avpriv_kbd_window_init(sdr->fm_window_p2, sdr->kbd_alpha, sdr->fm_block_size_p2);
- for(int i = sdr->fm_block_size_p2; i < 2 * sdr->fm_block_size_p2; i++) {
- sdr->fm_window_p2[i] = sdr->fm_window_p2[2*sdr->fm_block_size_p2 - i - 1];
- }
+ init_window(sdr, sdr->am_window, sdr->am_block_size);
+ init_window(sdr, sdr->fm_window, sdr->fm_block_size);
+ init_window(sdr, sdr->fm_window_p2, sdr->fm_block_size_p2);
if (sdr->waterfall_st_index >= 0) {
AVStream *st = s->streams[sdr->waterfall_st_index];
@@ -1986,6 +1984,16 @@ int ff_sdr_read_close(AVFormatContext *s)
av_freep(&sdr->block);
av_freep(&sdr->len2block);
av_freep(&sdr->window);
+
+ av_freep(&sdr->am_block);
+ av_freep(&sdr->am_iblock);
+ av_freep(&sdr->am_icarrier);
+ av_freep(&sdr->am_window);
+ av_freep(&sdr->fm_iside);
+ av_freep(&sdr->fm_block);
+ av_freep(&sdr->fm_iblock);
+ av_freep(&sdr->fm_icarrier);
+ av_freep(&sdr->fm_window);
av_freep(&sdr->fm_window_p2);
av_tx_uninit(&sdr->fft_ctx);
--
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".
^ permalink raw reply [flat|nested] 13+ messages in thread
* [FFmpeg-devel] [PATCH 10/12] avradio/sdr: Move tx contexts out of stream so its not duplicated
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
` (7 preceding siblings ...)
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 09/12] avradio/sdr: Move per stream arraies " Michael Niedermayer
@ 2023-07-11 21:19 ` Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 11/12] avradio/sdr: Pass AVStream instead of int to demodulate Michael Niedermayer
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdr.h | 10 +++++----
libavradio/sdrdemux.c | 48 +++++++++++++++++++++++--------------------
2 files changed, 32 insertions(+), 26 deletions(-)
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 8d7ab803d4..cb4b6dc68b 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -99,10 +99,6 @@ typedef struct FIFOElement {
} FIFOElement;
typedef struct SDRStream {
- AVTXContext *fft_ctx;
- AVTXContext *ifft_p2_ctx;
- av_tx_fn fft;
- av_tx_fn ifft_p2;
int processing_index;
float *out_buf;
@@ -172,9 +168,15 @@ typedef struct SDRContext {
float *fm_window_p2;
AVTXContext *am_ifft_ctx;
+ AVTXContext *am_fft_ctx;
AVTXContext *fm_ifft_ctx;
+ AVTXContext *fm_fft_ctx;
+ AVTXContext *fm_ifft_p2_ctx;
av_tx_fn am_ifft;
+ av_tx_fn am_fft;
av_tx_fn fm_ifft;
+ av_tx_fn fm_fft;
+ av_tx_fn fm_ifft_p2;
int am_mode; ///< AMMode but using int for generic option access
int emphasis_mode;
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 6442d251f6..5d58d81843 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -991,7 +991,7 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
//FIXME this only needs to be a RDFT
//CONSIDER, this and in fact alot can be done with bandpass and lowpass filters instead of FFTs, find out which is better
//CONSIDER synthesizing the carrier instead of IFFT, we have all parameters for that
- sst->fft(sst->fft_ctx, sdr->fm_block, sdr->fm_iblock, sizeof(AVComplexFloat));
+ sdr->fm_fft(sdr->fm_fft_ctx, sdr->fm_block, sdr->fm_iblock, sizeof(AVComplexFloat));
// Only the low N/2+1 are used the upper is just a reflection
carrier19_i_exact = find_am_carrier(sdr, sdr->fm_block, 2*sdr->fm_block_size, (void*)(sdr->fm_block + 1 + sdr->fm_block_size), carrier19_i, 10, 10);
@@ -1002,11 +1002,11 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
memset(sdr->fm_block + i, 0, 2*sdr->fm_block_size_p2 * sizeof(AVComplexFloat));
memcpy(sdr->fm_block + i, sdr->fm_block + carrier19_i, sizeof(AVComplexFloat)*(W+1));
memcpy(sdr->fm_block + i + 2*sdr->fm_block_size_p2 - W, sdr->fm_block + carrier19_i - W, sizeof(AVComplexFloat)*W);
- sst->ifft_p2(sst->ifft_p2_ctx, sdr->fm_icarrier, sdr->fm_block + i, sizeof(AVComplexFloat));
+ sdr->fm_ifft_p2(sdr->fm_ifft_p2_ctx, sdr->fm_icarrier, sdr->fm_block + i, sizeof(AVComplexFloat));
memcpy(sdr->fm_block + i, sdr->fm_block + 3*carrier19_i, sizeof(AVComplexFloat)*len2_4_i);
memcpy(sdr->fm_block + i + 2*sdr->fm_block_size_p2 - len2_4_i, sdr->fm_block + 3*carrier19_i - len2_4_i, sizeof(AVComplexFloat)*len2_4_i);
- sst->ifft_p2(sst->ifft_p2_ctx, sdr->fm_iside , sdr->fm_block + i, sizeof(AVComplexFloat));
+ sdr->fm_ifft_p2(sdr->fm_ifft_p2_ctx, sdr->fm_iside , sdr->fm_block + i, sizeof(AVComplexFloat));
synchronous_am_demodulationN(sdr->fm_iside, sdr->fm_icarrier, sdr->fm_window_p2, 2*sdr->fm_block_size_p2, 3);
ff_sdr_decode_rds(sdr, sst->station, sdr->fm_iside);
@@ -1014,12 +1014,12 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
memcpy(sdr->fm_block + i + 2*sdr->fm_block_size_p2 - len17_i, sdr->fm_block + 2*carrier19_i - len17_i, sizeof(AVComplexFloat)*len17_i);
apply_deemphasis(sdr, sdr->fm_block + i, sdr->fm_block_size_p2, sample_rate_p2, + 1);
apply_deemphasis(sdr, sdr->fm_block + i + 2*sdr->fm_block_size_p2, sdr->fm_block_size_p2, sample_rate_p2, - 1);
- sst->ifft_p2(sst->ifft_p2_ctx, sdr->fm_iside , sdr->fm_block + i, sizeof(AVComplexFloat));
+ sdr->fm_ifft_p2(sdr->fm_ifft_p2_ctx, sdr->fm_iside , sdr->fm_block + i, sizeof(AVComplexFloat));
synchronous_am_demodulationN(sdr->fm_iside, sdr->fm_icarrier, sdr->fm_window_p2, 2*sdr->fm_block_size_p2, 2);
}
memset(sdr->fm_block + len17_i, 0, (2*sdr->fm_block_size_p2 - len17_i) * sizeof(AVComplexFloat));
apply_deemphasis(sdr, sdr->fm_block, 2*sdr->fm_block_size_p2, sample_rate_p2, + 1);
- sst->ifft_p2(sst->ifft_p2_ctx, sdr->fm_iblock , sdr->fm_block, sizeof(AVComplexFloat));
+ sdr->fm_ifft_p2(sdr->fm_ifft_p2_ctx, sdr->fm_iblock , sdr->fm_block, sizeof(AVComplexFloat));
memset(sdr->fm_iblock + 2*sdr->fm_block_size_p2, 0 ,(2*sdr->fm_block_size -2*sdr->fm_block_size_p2) * sizeof(AVComplexFloat));
scale = 5 / (M_PI * 2*sdr->fm_block_size);
@@ -1096,11 +1096,6 @@ static void free_stream(SDRContext *sdr, int stream_index)
AVStream *st = s->streams[stream_index];
SDRStream *sst = st->priv_data;
- av_tx_uninit(&sst->fft_ctx);
- av_tx_uninit(&sst->ifft_p2_ctx);
- sst->fft = NULL;
- sst->ifft_p2 = NULL;
-
av_freep(&sst->out_buf);
}
@@ -1138,15 +1133,6 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
int block_size;
if (sst->station->modulation == FM) {
- //Allocate 2nd stage demodulation fields if needed
- ret = av_tx_init(&sst-> fft_ctx, &sst-> fft, AV_TX_FLOAT_FFT, 0, 2*sdr->fm_block_size , NULL, 0);
- if (ret < 0)
- return ret;
-
- ret = av_tx_init(&sst->ifft_p2_ctx, &sst->ifft_p2, AV_TX_FLOAT_FFT, 1, 2*sdr->fm_block_size_p2, NULL, 0);
- if (ret < 0)
- return ret;
-
block_size = sdr->fm_block_size;
} else
block_size = sdr->am_block_size;
@@ -1523,10 +1509,22 @@ int ff_sdr_common_init(AVFormatContext *s)
if (ret < 0)
return ret;
+ ret = av_tx_init(&sdr->am_fft_ctx, &sdr->am_fft, AV_TX_FLOAT_FFT, 0, 2*sdr->am_block_size , NULL, 0);
+ if (ret < 0)
+ return ret;
+
ret = av_tx_init(&sdr->fm_ifft_ctx, &sdr->fm_ifft, AV_TX_FLOAT_FFT, 1, 2*sdr->fm_block_size, NULL, 0);
if (ret < 0)
return ret;
+ ret = av_tx_init(&sdr->fm_fft_ctx, &sdr->fm_fft, AV_TX_FLOAT_FFT, 0, 2*sdr->fm_block_size , NULL, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = av_tx_init(&sdr->fm_ifft_p2_ctx, &sdr->fm_ifft_p2, AV_TX_FLOAT_FFT, 1, 2*sdr->fm_block_size_p2, NULL, 0);
+ if (ret < 0)
+ return ret;
+
init_window(sdr, sdr->window, sdr->block_size);
for (int i = 0; i < 2 * sdr->block_size; i++)
@@ -1998,10 +1996,16 @@ int ff_sdr_read_close(AVFormatContext *s)
av_tx_uninit(&sdr->fft_ctx);
av_tx_uninit(&sdr->am_ifft_ctx);
+ av_tx_uninit(&sdr->am_fft_ctx);
av_tx_uninit(&sdr->fm_ifft_ctx);
- sdr->fft = NULL;
- sdr->am_ifft = NULL;
- sdr->fm_ifft = NULL;
+ av_tx_uninit(&sdr->fm_fft_ctx);
+ av_tx_uninit(&sdr->fm_ifft_p2_ctx);
+ sdr->fft = NULL;
+ sdr->am_ifft = NULL;
+ sdr->am_fft = NULL;
+ sdr->fm_ifft = NULL;
+ sdr->fm_fft = NULL;
+ sdr->fm_ifft_p2 = NULL;
avio_close(sdr->dump_avio);
--
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".
^ permalink raw reply [flat|nested] 13+ messages in thread
* [FFmpeg-devel] [PATCH 11/12] avradio/sdr: Pass AVStream instead of int to demodulate
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
` (8 preceding siblings ...)
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 10/12] avradio/sdr: Move tx contexts out of stream so its not duplicated Michael Niedermayer
@ 2023-07-11 21:19 ` Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 12/12] avradio/sdr: Process RDS of all stations not just the current one Michael Niedermayer
2023-07-12 23:26 ` [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
thats less errror prone and simpler
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdr.h | 2 +-
libavradio/sdrdemux.c | 8 +++-----
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index cb4b6dc68b..3297584eae 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -241,7 +241,7 @@ typedef struct ModulationDescriptor {
/**
* Demodulate given station into packet
*/
- int (*demodulate)(SDRContext *sdr, int stream_index, AVPacket *pkt);
+ int (*demodulate)(SDRContext *sdr, AVStream *st, AVPacket *pkt);
} ModulationDescriptor;
typedef struct BandDescriptor {
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 5d58d81843..19dd0ef381 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -665,9 +665,8 @@ static av_always_inline void synchronous_am_demodulationN(AVComplexFloat *iblock
}
}
-static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt)
+static int demodulate_am(SDRContext *sdr, AVStream *st, AVPacket *pkt)
{
- AVStream *st = sdr->avfmt->streams[stream_index];
SDRStream *sst = st->priv_data;
double freq = sst->station->frequency;
int64_t bandwidth = sst->station->bandwidth;
@@ -934,9 +933,8 @@ static int probe_fm(SDRContext *sdr)
return 0;
}
-static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt)
+static int demodulate_fm(SDRContext *sdr, AVStream *st, AVPacket *pkt)
{
- AVStream *st = sdr->avfmt->streams[stream_index];
SDRStream *sst = st->priv_data;
Station *station = sst->station;
@@ -1653,7 +1651,7 @@ process_next_block:
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
if (sst->station) {
skip = 0;
- ret = ff_sdr_modulation_descs[ sst->station->modulation ].demodulate(sdr, stream_index, pkt);
+ ret = ff_sdr_modulation_descs[ sst->station->modulation ].demodulate(sdr, st, pkt);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "demodulation failed ret = %d\n", ret);
}
--
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".
^ permalink raw reply [flat|nested] 13+ messages in thread
* [FFmpeg-devel] [PATCH 12/12] avradio/sdr: Process RDS of all stations not just the current one
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
` (9 preceding siblings ...)
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 11/12] avradio/sdr: Pass AVStream instead of int to demodulate Michael Niedermayer
@ 2023-07-11 21:19 ` Michael Niedermayer
2023-07-12 23:26 ` [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdr.h | 3 +-
libavradio/sdrdemux.c | 69 +++++++++++++++++++++++++++++--------------
2 files changed, 49 insertions(+), 23 deletions(-)
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 3297584eae..6c4647823e 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -91,6 +91,7 @@ typedef struct Station {
int rds_ring_pos;
struct SDRStream *stream;
+ int processing_index;
} Station;
typedef struct FIFOElement {
@@ -241,7 +242,7 @@ typedef struct ModulationDescriptor {
/**
* Demodulate given station into packet
*/
- int (*demodulate)(SDRContext *sdr, AVStream *st, AVPacket *pkt);
+ int (*demodulate)(SDRContext *sdr, Station *station, AVStream *st, AVPacket *pkt);
} ModulationDescriptor;
typedef struct BandDescriptor {
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 19dd0ef381..e93cf4dd98 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -665,11 +665,11 @@ static av_always_inline void synchronous_am_demodulationN(AVComplexFloat *iblock
}
}
-static int demodulate_am(SDRContext *sdr, AVStream *st, AVPacket *pkt)
+static int demodulate_am(SDRContext *sdr, Station *station, AVStream *st, AVPacket *pkt)
{
SDRStream *sst = st->priv_data;
- double freq = sst->station->frequency;
- int64_t bandwidth = sst->station->bandwidth;
+ double freq = station->frequency;
+ int64_t bandwidth = station->bandwidth;
int index = lrint(F2INDEX(freq));
int len = (bandwidth * 2ll * sdr->block_size + sdr->sdr_sample_rate/2) / sdr->sdr_sample_rate;
float *newbuf;
@@ -933,10 +933,9 @@ static int probe_fm(SDRContext *sdr)
return 0;
}
-static int demodulate_fm(SDRContext *sdr, AVStream *st, AVPacket *pkt)
+static int demodulate_fm(SDRContext *sdr, Station *station, AVStream *st, AVPacket *pkt)
{
- SDRStream *sst = st->priv_data;
- Station *station = sst->station;
+ SDRStream *sst = st ? st->priv_data : NULL;
double freq = station->frequency;
int64_t bandwidth = station->bandwidth;
@@ -954,6 +953,8 @@ static int demodulate_fm(SDRContext *sdr, AVStream *st, AVPacket *pkt)
double carrier19_i_exact;
int W= 5;
+ av_assert0(!st || (sst == station->stream && sst->station == station));
+
//If only some of the bandwidth is available, just try with less
int len2 = FFMIN(index, 2*sdr->block_size - index);
if (len2 < len && len2 > len/2)
@@ -962,11 +963,7 @@ static int demodulate_fm(SDRContext *sdr, AVStream *st, AVPacket *pkt)
if (index + len >= 2*sdr->block_size ||
index - len < 0 ||
2*len + 1 > 2*sdr->fm_block_size)
- return AVERROR(ERANGE);
-
- newbuf = av_malloc(sizeof(*sst->out_buf) * 2 * sdr->fm_block_size);
- if (!newbuf)
- return AVERROR(ENOMEM);
+ return AVERROR(ERANGE);
i = 2*len+1;
memcpy(sdr->fm_block, sdr->block + index, sizeof(*sdr->fm_block) * (len + 1));
@@ -1006,20 +1003,29 @@ static int demodulate_fm(SDRContext *sdr, AVStream *st, AVPacket *pkt)
memcpy(sdr->fm_block + i + 2*sdr->fm_block_size_p2 - len2_4_i, sdr->fm_block + 3*carrier19_i - len2_4_i, sizeof(AVComplexFloat)*len2_4_i);
sdr->fm_ifft_p2(sdr->fm_ifft_p2_ctx, sdr->fm_iside , sdr->fm_block + i, sizeof(AVComplexFloat));
synchronous_am_demodulationN(sdr->fm_iside, sdr->fm_icarrier, sdr->fm_window_p2, 2*sdr->fm_block_size_p2, 3);
- ff_sdr_decode_rds(sdr, sst->station, sdr->fm_iside);
-
- memcpy(sdr->fm_block + i, sdr->fm_block + 2*carrier19_i, sizeof(AVComplexFloat)*len17_i);
- memcpy(sdr->fm_block + i + 2*sdr->fm_block_size_p2 - len17_i, sdr->fm_block + 2*carrier19_i - len17_i, sizeof(AVComplexFloat)*len17_i);
- apply_deemphasis(sdr, sdr->fm_block + i, sdr->fm_block_size_p2, sample_rate_p2, + 1);
- apply_deemphasis(sdr, sdr->fm_block + i + 2*sdr->fm_block_size_p2, sdr->fm_block_size_p2, sample_rate_p2, - 1);
- sdr->fm_ifft_p2(sdr->fm_ifft_p2_ctx, sdr->fm_iside , sdr->fm_block + i, sizeof(AVComplexFloat));
- synchronous_am_demodulationN(sdr->fm_iside, sdr->fm_icarrier, sdr->fm_window_p2, 2*sdr->fm_block_size_p2, 2);
+ ff_sdr_decode_rds(sdr, station, sdr->fm_iside);
+
+ if (st) {
+ memcpy(sdr->fm_block + i, sdr->fm_block + 2*carrier19_i, sizeof(AVComplexFloat)*len17_i);
+ memcpy(sdr->fm_block + i + 2*sdr->fm_block_size_p2 - len17_i, sdr->fm_block + 2*carrier19_i - len17_i, sizeof(AVComplexFloat)*len17_i);
+ apply_deemphasis(sdr, sdr->fm_block + i, sdr->fm_block_size_p2, sample_rate_p2, + 1);
+ apply_deemphasis(sdr, sdr->fm_block + i + 2*sdr->fm_block_size_p2, sdr->fm_block_size_p2, sample_rate_p2, - 1);
+ sdr->fm_ifft_p2(sdr->fm_ifft_p2_ctx, sdr->fm_iside , sdr->fm_block + i, sizeof(AVComplexFloat));
+ synchronous_am_demodulationN(sdr->fm_iside, sdr->fm_icarrier, sdr->fm_window_p2, 2*sdr->fm_block_size_p2, 2);
+ }
}
+ if (!st)
+ return 0;
+
memset(sdr->fm_block + len17_i, 0, (2*sdr->fm_block_size_p2 - len17_i) * sizeof(AVComplexFloat));
apply_deemphasis(sdr, sdr->fm_block, 2*sdr->fm_block_size_p2, sample_rate_p2, + 1);
sdr->fm_ifft_p2(sdr->fm_ifft_p2_ctx, sdr->fm_iblock , sdr->fm_block, sizeof(AVComplexFloat));
memset(sdr->fm_iblock + 2*sdr->fm_block_size_p2, 0 ,(2*sdr->fm_block_size -2*sdr->fm_block_size_p2) * sizeof(AVComplexFloat));
+ newbuf = av_malloc(sizeof(*sst->out_buf) * 2 * sdr->fm_block_size);
+ if (!newbuf)
+ return AVERROR(ENOMEM);
+
scale = 5 / (M_PI * 2*sdr->fm_block_size);
for(i = 0; i<sdr->fm_block_size_p2; i++) {
float m, q;
@@ -1651,7 +1657,7 @@ process_next_block:
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
if (sst->station) {
skip = 0;
- ret = ff_sdr_modulation_descs[ sst->station->modulation ].demodulate(sdr, st, pkt);
+ ret = ff_sdr_modulation_descs[ sst->station->modulation ].demodulate(sdr, sst->station, st, pkt);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "demodulation failed ret = %d\n", ret);
}
@@ -1659,6 +1665,8 @@ process_next_block:
} else
av_assert0(0);
sst->processing_index = 0;
+ if (sst->station)
+ sst->station->processing_index = 0;
if (pkt && !skip) {
pkt->stream_index = stream_index;
pkt->dts = (sdr->pts & (-1<<FREQ_BITS));
@@ -1671,6 +1679,18 @@ process_next_block:
}
}
+ if (sdr->width > 1) {
+ Station *station_list[1000];
+ int nb_stations = ff_sdr_find_stations(sdr, sdr->block_center_freq, sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
+ for (int i= 0; i<nb_stations; i++) {
+ Station *station = station_list[i];
+ if (station->stream || station->modulation != FM || !station->processing_index || !station->in_station_list)
+ continue;
+ ff_sdr_modulation_descs[ FM ].demodulate(sdr, station, NULL, NULL);
+ station->processing_index = 0;
+ }
+ }
+
pthread_mutex_lock(&sdr->mutex);
full_blocks = av_fifo_can_read(sdr->full_block_fifo) - 1;
ret = av_fifo_peek(sdr->full_block_fifo, &fifo_element, 2, 0);
@@ -1820,6 +1840,8 @@ process_next_block:
// windowed_block is unused now, we can fill it with the next blocks data
if (sdr->block_center_freq) {
+ Station *station_list[1000];
+ int nb_stations;
if (sdr->skip_probe-- <= 0) {
//Probing takes a bit of time, lets not do it every time
sdr->skip_probe = 5;
@@ -1835,6 +1857,7 @@ process_next_block:
create_stations(sdr);
}
+ nb_stations = ff_sdr_find_stations(sdr, sdr->block_center_freq, sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
if (sdr->mode == SingleStationMode) {
AVStream *st = s->streams[sdr->single_ch_audio_st_index];
SDRStream *sst = st->priv_data;
@@ -1845,8 +1868,6 @@ process_next_block:
return ret;
}
} else {
- Station *station_list[1000];
- int nb_stations = ff_sdr_find_stations(sdr, sdr->block_center_freq, sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
av_assert0(sdr->mode == AllStationMode);
for(int i = 0; i<nb_stations; i++) {
Station *station = station_list[i];
@@ -1881,6 +1902,10 @@ process_next_block:
SDRStream *sst = st->priv_data;
sst->processing_index += sdr->block_size;
}
+ for(int i = 0; i<nb_stations; i++) {
+ Station *station = station_list[i];
+ station->processing_index += sdr->block_size;
+ }
}
sdr->last_pts = sdr->pts;
--
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".
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory
2023-07-11 21:18 [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory Michael Niedermayer
` (10 preceding siblings ...)
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 12/12] avradio/sdr: Process RDS of all stations not just the current one Michael Niedermayer
@ 2023-07-12 23:26 ` Michael Niedermayer
11 siblings, 0 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-12 23:26 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 424 bytes --]
On Tue, Jul 11, 2023 at 11:18:59PM +0200, Michael Niedermayer wrote:
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
> libavradio/sdrdemux.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Will apply patchset
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Opposition brings concord. Out of discord comes the fairest harmony.
-- Heraclitus
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
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".
^ permalink raw reply [flat|nested] 13+ messages in thread