From: Michael Niedermayer <michael@niedermayer.cc> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: [FFmpeg-devel] [PATCH 4/9] avradio/sdr: Eliminate station list Date: Fri, 7 Jul 2023 19:22:19 +0200 Message-ID: <20230707172224.2368067-4-michael@niedermayer.cc> (raw) In-Reply-To: <20230707172224.2368067-1-michael@niedermayer.cc> Its redudnant with the AVTree information Makes the code simpler Signed-off-by: Michael Niedermayer <michael@niedermayer.cc> --- libavradio/sdr.h | 9 ---- libavradio/sdrdemux.c | 107 ++++++++++++++++++++++-------------------- 2 files changed, 55 insertions(+), 61 deletions(-) diff --git a/libavradio/sdr.h b/libavradio/sdr.h index 4b1543efd3..00066850f9 100644 --- a/libavradio/sdr.h +++ b/libavradio/sdr.h @@ -125,15 +125,6 @@ typedef struct SDRContext { char *dump_url; int fileheader_size; AVIOContext *dump_avio; - /** - * Current list of unambigously detected stations - */ - Station **station; - int nb_stations; - /** - * Current list of detected stations, these can be overlapping and low quality detections. - * Used for probing. Stations are not removed from this when added to station. - */ struct AVTreeNode *station_root; int width, height; int single_ch_audio_st_index; diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c index 7744ecdac0..769cf3ade6 100644 --- a/libavradio/sdrdemux.c +++ b/libavradio/sdrdemux.c @@ -183,7 +183,6 @@ static int create_station(SDRContext *sdr, Station *candidate_station) { void *tmp; int i; Station *best_station = NULL; - int best_station_index = -1; float drift = bandwidth/3.0; double best_distance = drift; int conflict = INT_MAX; @@ -193,27 +192,32 @@ static int create_station(SDRContext *sdr, Station *candidate_station) { if (candidate_station->in_station_list) return 0; - for (i=0; i<sdr->nb_stations; i++) { - double delta = fabs(sdr->station[i]->frequency - freq); + Station *station_list[1000]; + int nb_stations = 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); + + if (!s->in_station_list) + continue; + // Station already added, or we have 2 rather close stations //FIXME we want to make sure that the stronger station is not skiped but we also dont want to add a station twice - if (modulation == sdr->station[i]->modulation && delta < best_distance) { + if (modulation == s->modulation && delta < best_distance) { best_distance = delta; - best_station = sdr->station[i]; - best_station_index = i; + best_station = s; } - if (modulation != sdr->station[i]->modulation && delta < (bandwidth + sdr->station[i]->bandwidth)/2.1) { - conflict = FFMIN(conflict, sdr->station[i]->timeout); + if (modulation !=s->modulation && delta < (bandwidth + s->bandwidth)/2.1) { + conflict = FFMIN(conflict, s->timeout); // special case, lets not remove an actively listen to station, this can be done too but that needs more thought - if (sdr->station[i]->stream) + if (s->stream) conflict = 0; } } if (best_station) { if (score > best_station->score && conflict == INT_MAX) { int log_level = fabs(best_station->frequency - freq) < 3.0 ? AV_LOG_DEBUG : AV_LOG_WARNING; - av_log(sdr->avfmt, log_level, "Update station %d score:%f -> %f freq: %f %f -> %f\n", - best_station_index, + av_log(sdr->avfmt, log_level, "Update station score:%f -> %f freq: %f %f -> %f\n", best_station->score, score, best_station->frequency - freq, best_station->frequency, freq ); @@ -225,12 +229,9 @@ static int create_station(SDRContext *sdr, Station *candidate_station) { } candidate_station->in_station_list = 1; best_station->in_station_list = 0; - sdr->station[best_station_index] = candidate_station; } - return best_station_index; + return 2; } - Station *station_list[1000]; - int nb_stations = find_stations(sdr, sdr->block_center_freq, sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list)); nb_candidate_match += candidate_station->nb_frequency - 1; for (i=0; i<nb_stations; i++) { @@ -262,29 +263,23 @@ static int create_station(SDRContext *sdr, Station *candidate_station) { return -1; if (conflict < INT_MAX) { - for (i=0; i<sdr->nb_stations; i++) { - double delta = fabs(sdr->station[i]->frequency - freq); + for (i=0; i<nb_stations; i++) { + Station *s = station_list[i]; + double delta = fabs(s->frequency - freq); // We recheck that the stations we remove are not active because floating point could round differently - if (sdr->station[i]->stream == NULL && - modulation != sdr->station[i]->modulation && delta < (bandwidth + sdr->station[i]->bandwidth)/2.1) { + if (s->stream == NULL && + modulation != s->modulation && delta < (bandwidth + s->bandwidth)/2.1) { - sdr->station[i]->in_station_list = 0; - sdr->station[i--] = sdr->station[--sdr->nb_stations]; + s->in_station_list = 0; } } } - tmp = av_realloc_array(sdr->station, sdr->nb_stations+1, sizeof(*sdr->station)); - if (!tmp) - return AVERROR(ENOMEM); - sdr->station = tmp; - - sdr->station[sdr->nb_stations++] = 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); - return sdr->nb_stations - 1; + return 1; } static void create_stations(SDRContext *sdr) @@ -334,8 +329,8 @@ static void decay_stations(SDRContext *sdr) Station *station_list[1000]; int nb_stations = find_stations(sdr, sdr->block_center_freq, sdr->bandwidth*0.5, station_list, FF_ARRAY_ELEMS(station_list)); - for (int i=0; i<sdr->nb_stations; i++) { - Station *station = sdr->station[i]; + for (int i=0; i<nb_stations; i++) { + Station *station = station_list[i]; if (station->frequency - station->bandwidth/2 < sdr->block_center_freq - sdr->bandwidth/2 || station->frequency + station->bandwidth/2 > sdr->block_center_freq + sdr->bandwidth/2) @@ -343,21 +338,18 @@ static void decay_stations(SDRContext *sdr) if (station->stream) continue; - if (station->timeout++ > STATION_TIMEOUT) { - station->in_station_list = 0; - sdr->station[i--] = sdr->station[--sdr->nb_stations]; - } - } - - for (int i=0; i<nb_stations; i++) { - Station *station = station_list[i]; - - if (station->timeout++ > CANDIDATE_STATION_TIMEOUT && !station->in_station_list) { - struct AVTreeNode *next = NULL; - tree_remove(&sdr->station_root, station, station_cmp, &next); - av_freep(&next); + if (station->in_station_list) { + if (station->timeout++ > STATION_TIMEOUT) { + station->in_station_list = 0; + } + } else { + if (station->timeout++ > CANDIDATE_STATION_TIMEOUT) { + struct AVTreeNode *next = NULL; + tree_remove(&sdr->station_root, station, station_cmp, &next); + av_freep(&next); - free_station(station); + free_station(station); + } } } } @@ -1209,6 +1201,8 @@ static int snap2station(SDRContext *sdr, int *seek_direction) { double current_freq; double best_distance = INT64_MAX; Station *best_station = NULL; + Station *station_list[1000]; + int nb_stations = find_stations(sdr, sdr->block_center_freq, sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list)); if (sst->station) { current_freq = sst->station->frequency; @@ -1217,10 +1211,13 @@ static int snap2station(SDRContext *sdr, int *seek_direction) { } else current_freq = sdr->block_center_freq; - for(int i = 0; i<sdr->nb_stations; i++) { - Station *station = sdr->station[i]; + for(int i = 0; i<nb_stations; i++) { + Station *station = station_list[i]; double distance = station->frequency - current_freq; + if (!station->in_station_list) + continue; + if (distance * *seek_direction < 0 || station == sst->station) continue; distance = fabs(distance); @@ -1685,14 +1682,20 @@ static int vissualization(SDRContext *sdr, AVStream *st, AVPacket *pkt) for (int y= h2; y<h; y++) memcpy(pkt->data + 4*y*w, sst->frame_buffer + 4*(y + sst->frame_buffer_line - h2)*w, 4*w); - for(int station_index = 0; station_index<sdr->nb_stations; station_index++) { - Station *s = sdr->station[station_index]; + Station *station_list[1000]; + int nb_stations = find_stations(sdr, sdr->block_center_freq, sdr->sdr_sample_rate*0.6, station_list, FF_ARRAY_ELEMS(station_list)); + for(int station_index = 0; station_index<nb_stations; station_index++) { + Station *s = station_list[station_index]; double f = s->frequency; int xmid = 256*( f - sdr->block_center_freq + sdr->sdr_sample_rate/2) * w / sdr->sdr_sample_rate; char text[20]; int color = s->stream ? 64 : 32; int size = s->stream ? 181 : 128; int xd = size, yd = size; + + if (!s->in_station_list) + continue; + snprintf(text, sizeof(text), "%s %f Mhz", modulation_descs[s->modulation].shortname, f/1000000); @@ -1928,8 +1931,10 @@ process_next_block: } } else { av_assert0(sdr->mode == AllStationMode); - for(int i = 0; i<sdr->nb_stations; i++) { - Station *station = sdr->station[i]; + Station *station_list[1000]; + int nb_stations = 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) { /* audio stream */ AVStream *st = avformat_new_stream(s, NULL); @@ -2052,8 +2057,6 @@ int avpriv_sdr_read_close(AVFormatContext *s) sst->frame_size = 0; } - sdr->nb_stations = 0; - av_freep(&sdr->station); av_tree_enumerate(sdr->station_root, NULL, NULL, free_station_enu); av_tree_destroy(sdr->station_root); sdr->station_root = 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".
next prev parent reply other threads:[~2023-07-07 17:23 UTC|newest] Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-07-07 17:22 [FFmpeg-devel] [PATCH 1/9] avradio/sdr: use AVTree for candidate stations Michael Niedermayer 2023-07-07 17:22 ` [FFmpeg-devel] [PATCH 2/9] avradio/sdr: Consolidate candidate station entries Michael Niedermayer 2023-07-07 17:22 ` [FFmpeg-devel] [PATCH 3/9] avradio/sdr: consolidate the candidate station list with the main list Michael Niedermayer 2023-07-07 17:22 ` Michael Niedermayer [this message] 2023-07-07 17:22 ` [FFmpeg-devel] [PATCH 5/9] avradio/sdr: Allow user to adjust FM/AM thresholds Michael Niedermayer 2023-07-07 17:22 ` [FFmpeg-devel] [PATCH 6/9] avradio/sdrdemux: count timeout irrespective of a station being active Michael Niedermayer 2023-07-07 17:22 ` [FFmpeg-devel] [PATCH 7/9] avradio/sdr: Compute and use detection histogram Michael Niedermayer 2023-07-07 17:22 ` [FFmpeg-devel] [PATCH 8/9] avradio/sdrdemux: increase the FM station frequency tolerance Michael Niedermayer 2023-07-07 17:22 ` [FFmpeg-devel] [PATCH 9/9] avradio/sdrdemux: Use 2 differnt FM station detectors Michael Niedermayer 2023-07-08 15:42 ` [FFmpeg-devel] [PATCH 1/9] avradio/sdr: use AVTree for candidate stations Michael Niedermayer
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230707172224.2368067-4-michael@niedermayer.cc \ --to=michael@niedermayer.cc \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git