History

avfilter/avf_abitscope: refactor code & add trace mode

Paul B Mahol committed 4 years ago

Commit de0bb771 parent 72684d22 files · +92 −49Browse files

Unified · Split

2 files
  1. doc/filters.texi +3 −0
  2. libavfilter/avf_abitscope.c +89 −49
doc/filters.texi+3−0
@@ -25867,6 +25867,9 @@ Default value is @code{1024x256}. · 25866 unmodified lines
25867Specify list of colors separated by space or by '|' which will be used to25867Specify list of colors separated by space or by '|' which will be used to
25868draw channels. Unrecognized or missing colors will be replaced25868draw channels. Unrecognized or missing colors will be replaced
25869by white color.25869by white color.
25870
25871@item mode, m
25872Set output mode. Can be @code{bars} or @code{trace}. Default is @code{bars}.
25870@end table25873@end table
25871 25874
25872@section adrawgraph25875@section adrawgraph
libavfilter/avf_abitscope.c+89−49
@@ -34,13 +34,17 @@ typedef struct AudioBitScopeContext { · 33 unmodified lines
34 int w, h;34 int w, h;
35 AVRational frame_rate;35 AVRational frame_rate;
36 char *colors;36 char *colors;
37 int mode;
37 38
38 int nb_channels;39 int nb_channels;
39 int nb_samples;40 int nb_samples;
40 int depth;41 int depth;
42 int current_vpos;
41 uint8_t *fg;43 uint8_t *fg;
42 44
43 uint64_t counter[64];45 uint64_t counter[64];
46
47 AVFrame *outpicref;
44} AudioBitScopeContext;48} AudioBitScopeContext;
45 49
46#define OFFSET(x) offsetof(AudioBitScopeContext, x)50#define OFFSET(x) offsetof(AudioBitScopeContext, x)
@@ -52,6 +56,10 @@ static const AVOption abitscope_options[] = { · 5 unmodified lines
52 { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str="1024x256"}, 0, 0, FLAGS },56 { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str="1024x256"}, 0, 0, FLAGS },
53 { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str="1024x256"}, 0, 0, FLAGS },57 { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str="1024x256"}, 0, 0, FLAGS },
54 { "colors", "set channels colors", OFFSET(colors), AV_OPT_TYPE_STRING, {.str = "red|green|blue|yellow|orange|lime|pink|magenta|brown" }, 0, 0, FLAGS },58 { "colors", "set channels colors", OFFSET(colors), AV_OPT_TYPE_STRING, {.str = "red|green|blue|yellow|orange|lime|pink|magenta|brown" }, 0, 0, FLAGS },
59 { "mode", "set output mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FLAGS, "mode" },
60 { "m", "set output mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FLAGS, "mode" },
61 { "bars", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "mode" },
62 { "trace", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "mode" },
55 { NULL }63 { NULL }
56};64};
57 65
@@ -146,75 +154,99 @@ static void count_bits(AudioBitScopeContext *s, uint32_t sample, int max) · 88 unmodified lines
146 }154 }
147}155}
148 156
157
158#define BARS(type, depth) \
159 for (int ch = 0; ch < inlink->channels; ch++) { \
160 const type *in = (const type *)insamples->extended_data[ch]; \
161 const int w = outpicref->width / inlink->channels; \
162 const int h = outpicref->height / depth; \
163 const uint32_t color = AV_RN32(&s->fg[4 * ch]); \
164 \
165 memset(s->counter, 0, sizeof(s->counter)); \
166 for (int i = 0; i < insamples->nb_samples; i++) \
167 count_bits(s, in[i], depth); \
168 \
169 for (int b = 0; b < depth; b++) { \
170 for (int j = 1; j < h - 1; j++) { \
171 uint8_t *dst = outpicref->data[0] + (b * h + j) * outpicref->linesize[0] + w * ch * 4; \
172 const int ww = (s->counter[depth - b - 1] / (float)insamples->nb_samples) * (w - 1); \
173 \
174 for (int i = 0; i < ww; i++) { \
175 AV_WN32(&dst[i * 4], color); \
176 } \
177 } \
178 } \
179 }
180
181#define TRACE(type, depth) \
182 for (int ch = 0; ch < inlink->channels; ch++) { \
183 const int w = outpicref->width / inlink->channels; \
184 const type *in = (const type *)insamples->extended_data[ch]; \
185 const int wb = w / depth; \
186 int wv; \
187 \
188 memset(s->counter, 0, sizeof(s->counter)); \
189 for (int i = 0; i < insamples->nb_samples; i++) \
190 count_bits(s, in[i], depth); \
191 \
192 for (int b = 0; b < depth; b++) { \
193 uint8_t colors[4]; \
194 uint32_t color; \
195 uint8_t *dst = outpicref->data[0] + w * ch * 4 + wb * b * 4 + \
196 s->current_vpos * outpicref->linesize[0]; \
197 wv = (s->counter[depth - b - 1] * 255) / insamples->nb_samples; \
198 colors[0] = (wv * s->fg[ch * 4 + 0] + 127) / 255; \
199 colors[1] = (wv * s->fg[ch * 4 + 1] + 127) / 255; \
200 colors[2] = (wv * s->fg[ch * 4 + 2] + 127) / 255; \
201 colors[3] = (wv * s->fg[ch * 4 + 3] + 127) / 255; \
202 color = AV_RN32(colors); \
203 \
204 for (int x = 0; x < wb; x++) \
205 AV_WN32(&dst[x * 4], color); \
206 } \
207 }
208
149static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)209static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
150{210{
151 AVFilterContext *ctx = inlink->dst;211 AVFilterContext *ctx = inlink->dst;
152 AVFilterLink *outlink = ctx->outputs[0];212 AVFilterLink *outlink = ctx->outputs[0];
153 AudioBitScopeContext *s = ctx->priv;213 AudioBitScopeContext *s = ctx->priv;
154 AVFrame *outpicref;214 AVFrame *outpicref;
155 int ch, i, j, b;
156 215
157 outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h);216 if (s->mode == 0 || !s->outpicref) {
158 if (!outpicref) {217 outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h);
159 av_frame_free(&insamples);218 if (!outpicref) {
160 return AVERROR(ENOMEM);219 av_frame_free(&insamples);
220 return AVERROR(ENOMEM);
221 }
222
223 for (int i = 0; i < outlink->h; i++)
224 memset(outpicref->data[0] + i * outpicref->linesize[0], 0, outlink->w * 4);
225 if (!s->outpicref && s->mode == 1)
226 s->outpicref = outpicref;
161 }227 }
162 228
163 for (i = 0; i < outlink->h; i++)229 if (s->mode == 1) {
164 memset(outpicref->data[0] + i * outpicref->linesize[0], 0, outlink->w * 4);230 outpicref = av_frame_clone(s->outpicref);
231 if (!outpicref)
232 return AVERROR(ENOMEM);
233 }
165 234
166 outpicref->pts = insamples->pts;235 outpicref->pts = insamples->pts;
167 outpicref->sample_aspect_ratio = (AVRational){1,1};236 outpicref->sample_aspect_ratio = (AVRational){1,1};
168 237
169 switch (insamples->format) {238 switch (insamples->format) {
170 case AV_SAMPLE_FMT_S16P:239 case AV_SAMPLE_FMT_S16P:
171 for (ch = 0; ch < inlink->channels; ch++) {240 if (s->mode == 0) { BARS(uint16_t, 16) } else { TRACE(uint16_t, 16) }
172 uint16_t *in = (uint16_t *)insamples->extended_data[ch];
173 int w = outpicref->width / inlink->channels;
174 int h = outpicref->height / 16;
175 uint32_t color = AV_RN32(&s->fg[4 * ch]);
176
177 memset(s->counter, 0, sizeof(s->counter));
178 for (i = 0; i < insamples->nb_samples; i++)
179 count_bits(s, in[i], 16);
180
181 for (b = 0; b < 16; b++) {
182 for (j = 1; j < h - 1; j++) {
183 uint8_t *dst = outpicref->data[0] + (b * h + j) * outpicref->linesize[0] + w * ch * 4;
184 int ww = (s->counter[16 - b - 1] / (float)insamples->nb_samples) * (w - 1);
185
186 for (i = 0; i < ww; i++) {
187 AV_WN32(&dst[i * 4], color);
188 }
189 }
190 }
191 }
192 break;241 break;
193 case AV_SAMPLE_FMT_S32P:242 case AV_SAMPLE_FMT_S32P:
194 for (ch = 0; ch < inlink->channels; ch++) {243 if (s->mode == 0) { BARS(uint32_t, 32) } else { TRACE(uint32_t, 32) }
195 uint32_t *in = (uint32_t *)insamples->extended_data[ch];
196 int w = outpicref->width / inlink->channels;
197 int h = outpicref->height / 32;
198 uint32_t color = AV_RN32(&s->fg[4 * ch]);
199
200 memset(s->counter, 0, sizeof(s->counter));
201 for (i = 0; i < insamples->nb_samples; i++)
202 count_bits(s, in[i], 32);
203
204 for (b = 0; b < 32; b++) {
205 for (j = 1; j < h - 1; j++) {
206 uint8_t *dst = outpicref->data[0] + (b * h + j) * outpicref->linesize[0] + w * ch * 4;
207 int ww = (s->counter[32 - b - 1] / (float)insamples->nb_samples) * (w - 1);
208
209 for (i = 0; i < ww; i++) {
210 AV_WN32(&dst[i * 4], color);
211 }
212 }
213 }
214 }
215 break;244 break;
216 }245 }
217 246
247 s->current_vpos++;
248 if (s->current_vpos >= outlink->h)
249 s->current_vpos = 0;
218 av_frame_free(&insamples);250 av_frame_free(&insamples);
219 251
220 return ff_filter_frame(outlink, outpicref);252 return ff_filter_frame(outlink, outpicref);
@@ -242,6 +274,13 @@ static int activate(AVFilterContext *ctx) · 21 unmodified lines
242 return FFERROR_NOT_READY;274 return FFERROR_NOT_READY;
243}275}
244 276
277static av_cold void uninit(AVFilterContext *ctx)
278{
279 AudioBitScopeContext *s = ctx->priv;
280
281 av_frame_free(&s->outpicref);
282}
283
245static const AVFilterPad inputs[] = {284static const AVFilterPad inputs[] = {
246 {285 {
247 .name = "default",286 .name = "default",
@@ -265,6 +304,7 @@ const AVFilter ff_avf_abitscope = { · 17 unmodified lines
265 FILTER_INPUTS(inputs),304 FILTER_INPUTS(inputs),
266 FILTER_OUTPUTS(outputs),305 FILTER_OUTPUTS(outputs),
267 FILTER_QUERY_FUNC(query_formats),306 FILTER_QUERY_FUNC(query_formats),
307 .uninit = uninit,
268 .activate = activate,308 .activate = activate,
269 .priv_class = &abitscope_class,309 .priv_class = &abitscope_class,
270};310};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t