Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 01/12] avradio/sdrdemux: Fix use of uninitialized memory
@ 2023-07-11 21:18 Michael Niedermayer
  2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 02/12] avradio/rds: Implement burst error decoder Michael Niedermayer
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Michael Niedermayer @ 2023-07-11 21:18 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavradio/sdrdemux.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index a34f784e63..a37018fd2f 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -1144,7 +1144,7 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
 
             sst->rds_ring_size = ceil((2*105 / 1187.5 + 2.0*block_time) * sst->block_size_p2 / block_time);
 
-            sst->rds_ring  = av_malloc(sizeof(*sst->rds_ring ) * sst->rds_ring_size);
+            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)
@@ -1156,7 +1156,7 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station)
             }
         }
 
-        sst->out_buf   = av_malloc(sizeof(*sst->out_buf)  * 2 * sst->block_size);
+        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);
-- 
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 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

end of thread, other threads:[~2023-07-12 23:26 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [FFmpeg-devel] [PATCH 04/12] avradio/sdr: Move rds_ring to Station Michael Niedermayer
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 ` [FFmpeg-devel] [PATCH 06/12] avradio/sdr: Warnings cleanup Michael Niedermayer
2023-07-11 21:19 ` [FFmpeg-devel] [PATCH 07/12] avradio/rds: warnings cleanup Michael Niedermayer
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 ` [FFmpeg-devel] [PATCH 09/12] avradio/sdr: Move per stream arraies " 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
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 ` [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

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git