diff options
author | Paul B Mahol <onemda@gmail.com> | 2023-05-30 19:08:02 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2023-05-30 19:21:13 +0200 |
commit | 862ebbf2edb515b7685952cce8b8b6c8bacc9470 (patch) | |
tree | 99393cb8a111830d8da359d6182e4e69ba99b4a2 /libavfilter/avf_abitscope.c | |
parent | 1636fb415aac8747222bb35efb75555f8bc8772d (diff) | |
download | ffmpeg-862ebbf2edb515b7685952cce8b8b6c8bacc9470.tar.gz |
avfilter/avf_abitscope: refactor bit counting for histogram
This helps compiler figure out it can unroll loop and give 4x speedup.
Diffstat (limited to 'libavfilter/avf_abitscope.c')
-rw-r--r-- | libavfilter/avf_abitscope.c | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/libavfilter/avf_abitscope.c b/libavfilter/avf_abitscope.c index 782d57e03a..c74970981e 100644 --- a/libavfilter/avf_abitscope.c +++ b/libavfilter/avf_abitscope.c @@ -148,25 +148,29 @@ static int config_output(AVFilterLink *outlink) return 0; } +#define BITCOUNTER(type, depth, one) \ + memset(counter, 0, sizeof(s->counter)); \ + for (int i = 0; i < nb_samples; i++) { \ + const type x = in[i]; \ + for (int j = 0; j < depth && x; j++) \ + counter[j] += !!(x & (one << j)); \ + } + #define BARS(type, depth, one) \ for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { \ + const int nb_samples = insamples->nb_samples; \ const type *in = (const type *)insamples->extended_data[ch]; \ const int w = outpicref->width / inlink->ch_layout.nb_channels; \ const int h = outpicref->height / depth; \ const uint32_t color = AV_RN32(&s->fg[4 * ch]); \ + uint64_t *counter = s->counter; \ \ - memset(s->counter, 0, sizeof(s->counter)); \ - for (int i = 0; i < insamples->nb_samples; i++) { \ - for (int j = 0; j < depth; j++) { \ - if (in[i] & (one << j)) \ - s->counter[j]++; \ - } \ - } \ + BITCOUNTER(type, depth, one) \ \ for (int b = 0; b < depth; b++) { \ for (int j = 1; j < h - 1; j++) { \ uint8_t *dst = outpicref->data[0] + (b * h + j) * outpicref->linesize[0] + w * ch * 4; \ - const int ww = (s->counter[depth - b - 1] / (float)insamples->nb_samples) * (w - 1); \ + const int ww = (counter[depth - b - 1] / (float)nb_samples) * (w - 1); \ \ for (int i = 0; i < ww; i++) { \ AV_WN32(&dst[i * 4], color); \ @@ -177,25 +181,21 @@ static int config_output(AVFilterLink *outlink) #define DO_TRACE(type, depth, one) \ for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { \ + const int nb_samples = insamples->nb_samples; \ const int w = outpicref->width / inlink->ch_layout.nb_channels; \ const type *in = (const type *)insamples->extended_data[ch]; \ + uint64_t *counter = s->counter; \ const int wb = w / depth; \ int wv; \ \ - memset(s->counter, 0, sizeof(s->counter)); \ - for (int i = 0; i < insamples->nb_samples; i++) { \ - for (int j = 0; j < depth; j++) { \ - if (in[i] & (one << j)) \ - s->counter[j]++; \ - } \ - } \ + BITCOUNTER(type, depth, one) \ \ for (int b = 0; b < depth; b++) { \ uint8_t colors[4]; \ uint32_t color; \ uint8_t *dst = outpicref->data[0] + w * ch * 4 + wb * b * 4 + \ s->current_vpos * outpicref->linesize[0]; \ - wv = (s->counter[depth - b - 1] * 255) / insamples->nb_samples; \ + wv = (counter[depth - b - 1] * 255) / nb_samples; \ colors[0] = (wv * s->fg[ch * 4 + 0] + 127) / 255; \ colors[1] = (wv * s->fg[ch * 4 + 1] + 127) / 255; \ colors[2] = (wv * s->fg[ch * 4 + 2] + 127) / 255; \ |