FFmpeg  4.0
avf_showvolume.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/avstring.h"
23 #include "libavutil/eval.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/parseutils.h"
28 #include "avfilter.h"
29 #include "formats.h"
30 #include "audio.h"
31 #include "video.h"
32 #include "internal.h"
33 
34 static const char *const var_names[] = { "VOLUME", "CHANNEL", "PEAK", NULL };
37 
38 typedef struct ShowVolumeContext {
39  const AVClass *class;
40  int w, h;
41  int b;
42  double f;
44  char *color;
46  int step;
47  float bgopacity;
48  int mode;
49 
52  int draw_text;
54  double *values;
55  uint32_t *color_lut;
56  float *max;
57  float rms_factor;
59 
60  double draw_persistent_duration; /* in second */
62  int persistent_max_frames; /* number of frames to check max value */
63  float *max_persistent; /* max value for draw_persistent_max for each channel */
64  int *nb_frames_max_display; /* number of frame for each channel, for displaying the max value */
65 
66  void (*meter)(float *src, int nb_samples, float *max, float factor);
68 
69 #define OFFSET(x) offsetof(ShowVolumeContext, x)
70 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
71 
72 static const AVOption showvolume_options[] = {
73  { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, INT_MAX, FLAGS },
74  { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, INT_MAX, FLAGS },
75  { "b", "set border width", OFFSET(b), AV_OPT_TYPE_INT, {.i64=1}, 0, 5, FLAGS },
76  { "w", "set channel width", OFFSET(w), AV_OPT_TYPE_INT, {.i64=400}, 80, 8192, FLAGS },
77  { "h", "set channel height", OFFSET(h), AV_OPT_TYPE_INT, {.i64=20}, 1, 900, FLAGS },
78  { "f", "set fade", OFFSET(f), AV_OPT_TYPE_DOUBLE, {.dbl=0.95}, 0, 1, FLAGS },
79  { "c", "set volume color expression", OFFSET(color), AV_OPT_TYPE_STRING, {.str="PEAK*255+floor((1-PEAK)*255)*256+0xff000000"}, 0, 0, FLAGS },
80  { "t", "display channel names", OFFSET(draw_text), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
81  { "v", "display volume value", OFFSET(draw_volume), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
82  { "dm", "duration for max value display", OFFSET(draw_persistent_duration), AV_OPT_TYPE_DOUBLE, {.dbl=0.}, 0, 9000, FLAGS},
83  { "dmc","set color of the max value line", OFFSET(persistant_max_rgba), AV_OPT_TYPE_COLOR, {.str = "orange"}, CHAR_MIN, CHAR_MAX, FLAGS },
84  { "o", "set orientation", OFFSET(orientation), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "orientation" },
85  { "h", "horizontal", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "orientation" },
86  { "v", "vertical", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "orientation" },
87  { "s", "set step size", OFFSET(step), AV_OPT_TYPE_INT, {.i64=0}, 0, 5, FLAGS },
88  { "p", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS },
89  { "m", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "mode" },
90  { "p", "peak", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "mode" },
91  { "r", "rms", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "mode" },
92  { "ds", "set display scale", OFFSET(display_scale), AV_OPT_TYPE_INT, {.i64=LINEAR}, LINEAR, NB_DISPLAY_SCALE - 1, FLAGS, "display_scale" },
93  { "lin", "linear", 0, AV_OPT_TYPE_CONST, {.i64=LINEAR}, 0, 0, FLAGS, "display_scale" },
94  { "log", "log", 0, AV_OPT_TYPE_CONST, {.i64=LOG}, 0, 0, FLAGS, "display_scale" },
95  { NULL }
96 };
97 
98 AVFILTER_DEFINE_CLASS(showvolume);
99 
101 {
102  ShowVolumeContext *s = ctx->priv;
103  int ret;
104 
105  if (s->color) {
106  ret = av_expr_parse(&s->c_expr, s->color, var_names,
107  NULL, NULL, NULL, NULL, 0, ctx);
108  if (ret < 0)
109  return ret;
110  }
111 
112  return 0;
113 }
114 
116 {
119  AVFilterLink *inlink = ctx->inputs[0];
120  AVFilterLink *outlink = ctx->outputs[0];
122  static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGBA, AV_PIX_FMT_NONE };
123  int ret;
124 
125  formats = ff_make_format_list(sample_fmts);
126  if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0)
127  return ret;
128 
129  layouts = ff_all_channel_counts();
130  if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0)
131  return ret;
132 
133  formats = ff_all_samplerates();
134  if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0)
135  return ret;
136 
137  formats = ff_make_format_list(pix_fmts);
138  if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
139  return ret;
140 
141  return 0;
142 }
143 
144 static void find_peak(float *src, int nb_samples, float *peak, float factor)
145 {
146  int i;
147 
148  *peak = 0;
149  for (i = 0; i < nb_samples; i++)
150  *peak = FFMAX(*peak, FFABS(src[i]));
151 }
152 
153 static void find_rms(float *src, int nb_samples, float *rms, float factor)
154 {
155  int i;
156 
157  for (i = 0; i < nb_samples; i++)
158  *rms += factor * (src[i] * src[i] - *rms);
159 }
160 
161 static int config_input(AVFilterLink *inlink)
162 {
163  AVFilterContext *ctx = inlink->dst;
164  ShowVolumeContext *s = ctx->priv;
165  int nb_samples;
166 
167  nb_samples = FFMAX(1024, ((double)inlink->sample_rate / av_q2d(s->frame_rate)) + 0.5);
168  inlink->partial_buf_size =
169  inlink->min_samples =
170  inlink->max_samples = nb_samples;
171  s->values = av_calloc(inlink->channels * VAR_VARS_NB, sizeof(double));
172  if (!s->values)
173  return AVERROR(ENOMEM);
174 
175  s->color_lut = av_calloc(s->w, sizeof(*s->color_lut) * inlink->channels);
176  if (!s->color_lut)
177  return AVERROR(ENOMEM);
178 
179  s->max = av_calloc(inlink->channels, sizeof(*s->max));
180  if (!s->max)
181  return AVERROR(ENOMEM);
182 
183  s->rms_factor = 10000. / inlink->sample_rate;
184 
185  switch (s->mode) {
186  case 0: s->meter = find_peak; break;
187  case 1: s->meter = find_rms; break;
188  default: return AVERROR_BUG;
189  }
190 
191  if (s->draw_persistent_duration > 0.) {
193  s->max_persistent = av_calloc(inlink->channels * s->persistent_max_frames, sizeof(*s->max_persistent));
195  }
196  return 0;
197 }
198 
199 static int config_output(AVFilterLink *outlink)
200 {
201  ShowVolumeContext *s = outlink->src->priv;
202  AVFilterLink *inlink = outlink->src->inputs[0];
203  int ch;
204 
205  if (s->orientation) {
206  outlink->h = s->w;
207  outlink->w = s->h * inlink->channels + (inlink->channels - 1) * s->b;
208  } else {
209  outlink->w = s->w;
210  outlink->h = s->h * inlink->channels + (inlink->channels - 1) * s->b;
211  }
212 
213  outlink->sample_aspect_ratio = (AVRational){1,1};
214  outlink->frame_rate = s->frame_rate;
215 
216  for (ch = 0; ch < inlink->channels; ch++) {
217  int i;
218 
219  for (i = 0; i < s->w; i++) {
220  float max = i / (float)(s->w - 1);
221 
222  s->values[ch * VAR_VARS_NB + VAR_PEAK] = max;
223  s->values[ch * VAR_VARS_NB + VAR_VOLUME] = 20.0 * log10(max);
224  s->values[ch * VAR_VARS_NB + VAR_CHANNEL] = ch;
225  s->color_lut[ch * s->w + i] = av_expr_eval(s->c_expr, &s->values[ch * VAR_VARS_NB], NULL);
226  }
227  }
228 
229  return 0;
230 }
231 
232 static void drawtext(AVFrame *pic, int x, int y, const char *txt, int o)
233 {
234  const uint8_t *font;
235  int font_height;
236  int i;
237 
238  font = avpriv_cga_font, font_height = 8;
239 
240  for (i = 0; txt[i]; i++) {
241  int char_y, mask;
242 
243  if (o) { /* vertical orientation */
244  for (char_y = font_height - 1; char_y >= 0; char_y--) {
245  uint8_t *p = pic->data[0] + (y + i * 10) * pic->linesize[0] + x * 4;
246  for (mask = 0x80; mask; mask >>= 1) {
247  if (font[txt[i] * font_height + font_height - 1 - char_y] & mask)
248  AV_WN32(&p[char_y * 4], ~AV_RN32(&p[char_y * 4]));
249  p += pic->linesize[0];
250  }
251  }
252  } else { /* horizontal orientation */
253  uint8_t *p = pic->data[0] + y * pic->linesize[0] + (x + i * 8) * 4;
254  for (char_y = 0; char_y < font_height; char_y++) {
255  for (mask = 0x80; mask; mask >>= 1) {
256  if (font[txt[i] * font_height + char_y] & mask)
257  AV_WN32(p, ~AV_RN32(p));
258  p += 4;
259  }
260  p += pic->linesize[0] - 8 * 4;
261  }
262  }
263  }
264 }
265 
267 {
268  int i, j;
269  const uint32_t bg = (uint32_t)(s->bgopacity * 255) << 24;
270 
271  for (i = 0; i < outlink->h; i++) {
272  uint32_t *dst = (uint32_t *)(s->out->data[0] + i * s->out->linesize[0]);
273  for (j = 0; j < outlink->w; j++)
274  AV_WN32A(dst + j, bg);
275  }
276 }
277 
278 static inline int calc_max_draw(ShowVolumeContext *s, AVFilterLink *outlink, float max)
279 {
280  float max_val;
281  if (s->display_scale == LINEAR) {
282  max_val = max;
283  } else { /* log */
284  max_val = av_clipf(0.21 * log10(max) + 1, 0, 1);
285  }
286  if (s->orientation) { /* vertical */
287  return outlink->h - outlink->h * max_val;
288  } else { /* horizontal */
289  return s->w * max_val;
290  }
291 }
292 
293 static inline void calc_persistent_max(ShowVolumeContext *s, float max, int channel)
294 {
295  /* update max value for persistent max display */
296  if ((max >= s->max_persistent[channel]) || (s->nb_frames_max_display[channel] >= s->persistent_max_frames)) { /* update max value for display */
297  s->max_persistent[channel] = max;
299  } else {
300  s->nb_frames_max_display[channel] += 1; /* incremente display frame count */
301  }
302 }
303 
304 static inline void draw_max_line(ShowVolumeContext *s, int max_draw, int channel)
305 {
306  int k;
307  if (s->orientation) { /* vertical */
308  uint8_t *dst = s->out->data[0] + max_draw * s->out->linesize[0] + channel * (s->b + s->h) * 4;
309  for (k = 0; k < s->h; k++) {
310  memcpy(dst + k * 4, s->persistant_max_rgba, sizeof(s->persistant_max_rgba));
311  }
312  } else { /* horizontal */
313  for (k = 0; k < s->h; k++) {
314  uint8_t *dst = s->out->data[0] + (channel * s->h + channel * s->b + k) * s->out->linesize[0];
315  memcpy(dst + max_draw * 4, s->persistant_max_rgba, sizeof(s->persistant_max_rgba));
316  }
317  }
318 }
319 
320 static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
321 {
322  AVFilterContext *ctx = inlink->dst;
323  AVFilterLink *outlink = ctx->outputs[0];
324  ShowVolumeContext *s = ctx->priv;
325  const int step = s->step;
326  int c, j, k, max_draw;
327  AVFrame *out;
328 
329  if (!s->out || s->out->width != outlink->w ||
330  s->out->height != outlink->h) {
331  av_frame_free(&s->out);
332  s->out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
333  if (!s->out) {
334  av_frame_free(&insamples);
335  return AVERROR(ENOMEM);
336  }
337  clear_picture(s, outlink);
338  }
339  s->out->pts = insamples->pts;
340 
341  if ((s->f < 1.) && (s->f > 0.)) {
342  for (j = 0; j < outlink->h; j++) {
343  uint8_t *dst = s->out->data[0] + j * s->out->linesize[0];
344  const uint32_t alpha = s->bgopacity * 255;
345 
346  for (k = 0; k < outlink->w; k++) {
347  dst[k * 4 + 0] = FFMAX(dst[k * 4 + 0] * s->f, 0);
348  dst[k * 4 + 1] = FFMAX(dst[k * 4 + 1] * s->f, 0);
349  dst[k * 4 + 2] = FFMAX(dst[k * 4 + 2] * s->f, 0);
350  dst[k * 4 + 3] = FFMAX(dst[k * 4 + 3] * s->f, alpha);
351  }
352  }
353  } else if (s->f == 0.) {
354  clear_picture(s, outlink);
355  }
356 
357  if (s->orientation) { /* vertical */
358  for (c = 0; c < inlink->channels; c++) {
359  float *src = (float *)insamples->extended_data[c];
360  uint32_t *lut = s->color_lut + s->w * c;
361  float max;
362 
363  s->meter(src, insamples->nb_samples, &s->max[c], s->rms_factor);
364  max = s->max[c];
365 
366  s->values[c * VAR_VARS_NB + VAR_VOLUME] = 20.0 * log10(max);
367  max = av_clipf(max, 0, 1);
368  max_draw = calc_max_draw(s, outlink, max);
369 
370  for (j = max_draw; j < s->w; j++) {
371  uint8_t *dst = s->out->data[0] + j * s->out->linesize[0] + c * (s->b + s->h) * 4;
372  for (k = 0; k < s->h; k++) {
373  AV_WN32A(&dst[k * 4], lut[s->w - j - 1]);
374  if (j & step)
375  j += step;
376  }
377  }
378 
379  if (s->h >= 8 && s->draw_text) {
381  if (!channel_name)
382  continue;
383  drawtext(s->out, c * (s->h + s->b) + (s->h - 10) / 2, outlink->h - 35, channel_name, 1);
384  }
385 
386  if (s->draw_persistent_duration > 0.) {
387  calc_persistent_max(s, max, c);
388  max_draw = FFMAX(0, calc_max_draw(s, outlink, s->max_persistent[c]) - 1);
389  draw_max_line(s, max_draw, c);
390  }
391  }
392  } else { /* horizontal */
393  for (c = 0; c < inlink->channels; c++) {
394  float *src = (float *)insamples->extended_data[c];
395  uint32_t *lut = s->color_lut + s->w * c;
396  float max;
397 
398  s->meter(src, insamples->nb_samples, &s->max[c], s->rms_factor);
399  max = s->max[c];
400 
401  s->values[c * VAR_VARS_NB + VAR_VOLUME] = 20.0 * log10(max);
402  max = av_clipf(max, 0, 1);
403  max_draw = calc_max_draw(s, outlink, max);
404 
405  for (j = 0; j < s->h; j++) {
406  uint8_t *dst = s->out->data[0] + (c * s->h + c * s->b + j) * s->out->linesize[0];
407 
408  for (k = 0; k < max_draw; k++) {
409  AV_WN32A(dst + k * 4, lut[k]);
410  if (k & step)
411  k += step;
412  }
413  }
414 
415  if (s->h >= 8 && s->draw_text) {
417  if (!channel_name)
418  continue;
419  drawtext(s->out, 2, c * (s->h + s->b) + (s->h - 8) / 2, channel_name, 0);
420  }
421 
422  if (s->draw_persistent_duration > 0.) {
423  calc_persistent_max(s, max, c);
424  max_draw = FFMAX(0, calc_max_draw(s, outlink, s->max_persistent[c]) - 1);
425  draw_max_line(s, max_draw, c);
426  }
427  }
428  }
429 
430  av_frame_free(&insamples);
431  out = av_frame_clone(s->out);
432  if (!out)
433  return AVERROR(ENOMEM);
435 
436  /* draw volume level */
437  for (c = 0; c < inlink->channels && s->h >= 8 && s->draw_volume; c++) {
438  char buf[16];
439 
440  if (s->orientation) { /* vertical */
441  snprintf(buf, sizeof(buf), "%.2f", s->values[c * VAR_VARS_NB + VAR_VOLUME]);
442  drawtext(out, c * (s->h + s->b) + (s->h - 8) / 2, 2, buf, 1);
443  } else { /* horizontal */
444  snprintf(buf, sizeof(buf), "%.2f", s->values[c * VAR_VARS_NB + VAR_VOLUME]);
445  drawtext(out, FFMAX(0, s->w - 8 * (int)strlen(buf)), c * (s->h + s->b) + (s->h - 8) / 2, buf, 0);
446  }
447  }
448 
449  return ff_filter_frame(outlink, out);
450 }
451 
453 {
454  ShowVolumeContext *s = ctx->priv;
455 
456  av_frame_free(&s->out);
457  av_expr_free(s->c_expr);
458  av_freep(&s->values);
459  av_freep(&s->color_lut);
460  av_freep(&s->max);
461 }
462 
463 static const AVFilterPad showvolume_inputs[] = {
464  {
465  .name = "default",
466  .type = AVMEDIA_TYPE_AUDIO,
467  .config_props = config_input,
468  .filter_frame = filter_frame,
469  },
470  { NULL }
471 };
472 
473 static const AVFilterPad showvolume_outputs[] = {
474  {
475  .name = "default",
476  .type = AVMEDIA_TYPE_VIDEO,
477  .config_props = config_output,
478  },
479  { NULL }
480 };
481 
483  .name = "showvolume",
484  .description = NULL_IF_CONFIG_SMALL("Convert input audio volume to video output."),
485  .init = init,
486  .uninit = uninit,
487  .query_formats = query_formats,
488  .priv_size = sizeof(ShowVolumeContext),
489  .inputs = showvolume_inputs,
490  .outputs = showvolume_outputs,
491  .priv_class = &showvolume_class,
492 };
float, planar
Definition: samplefmt.h:69
#define NULL
Definition: coverity.c:32
uint8_t persistant_max_rgba[4]
const char * s
Definition: avisynth_c.h:768
static float alpha(float a)
This structure describes decoded (raw) audio or video data.
Definition: frame.h:218
AVOption.
Definition: opt.h:246
AVFilter ff_avf_showvolume
uint32_t * color_lut
Main libavfilter public API header.
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(INT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&HAVE_MMX) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
void(* meter)(float *src, int nb_samples, float *max, float factor)
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:679
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
static void drawtext(AVFrame *pic, int x, int y, const char *txt, int o)
#define src
Definition: vp8dsp.c:254
static void calc_persistent_max(ShowVolumeContext *s, float max, int channel)
#define AV_WN32A(p, v)
Definition: intreadwrite.h:538
static const AVOption showvolume_options[]
static void find_rms(float *src, int nb_samples, float *rms, float factor)
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
DisplayScale
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:435
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
static const AVFilterPad showvolume_outputs[]
uint8_t
#define av_cold
Definition: attributes.h:82
AVOptions.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:311
Definition: eval.c:157
#define OFFSET(x)
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AVRational frame_rate
A filter pad used for either input or output.
Definition: internal.h:54
int width
Definition: frame.h:276
const uint8_t avpriv_cga_font[2048]
Definition: xga_font_data.c:29
static const uint16_t mask[17]
Definition: lzw.c:38
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void * priv
private data for use by the filter
Definition: avfilter.h:353
static void draw_max_line(ShowVolumeContext *s, int max_draw, int channel)
#define FFMAX(a, b)
Definition: common.h:94
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:89
uint64_t channel_layout
Channel layout of the audio data.
Definition: frame.h:396
audio channel layout utility functions
static void find_peak(float *src, int nb_samples, float *peak, float factor)
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:440
AVFormatContext * ctx
Definition: movenc.c:48
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
static const AVFilterPad showvolume_inputs[]
static int config_output(AVFilterLink *outlink)
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:538
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
A list of supported channel layouts.
Definition: formats.h:85
static void clear_picture(ShowVolumeContext *s, AVFilterLink *outlink)
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
typedef void(RENAME(mix_any_func_type))
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:334
static int query_formats(AVFilterContext *ctx)
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:249
void * buf
Definition: avisynth_c.h:690
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
Rational number (pair of numerator and denominator).
Definition: rational.h:58
static int calc_max_draw(ShowVolumeContext *s, AVFilterLink *outlink, float max)
offset must point to AVRational
Definition: opt.h:236
static av_cold int init(AVFilterContext *ctx)
static const int factor[16]
Definition: vf_pp7.c:75
const char * name
Filter name.
Definition: avfilter.h:148
#define snprintf
Definition: snprintf.h:34
#define AV_RN32(p)
Definition: intreadwrite.h:364
misc parsing utilities
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:266
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:395
int av_frame_make_writable(AVFrame *frame)
Ensure that the frame data is writable, avoiding data copy if possible.
Definition: frame.c:609
#define FLAGS
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:232
int
double draw_persistent_duration
#define AV_WN32(p, v)
Definition: intreadwrite.h:376
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
static double c[64]
channel
Use these values when setting the channel map with ebur128_set_channel().
Definition: ebur128.h:39
static int config_input(AVFilterLink *inlink)
static av_cold void uninit(AVFilterContext *ctx)
static const char *const var_names[]
const char * av_get_channel_name(uint64_t channel)
Get the name of a given channel.
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:734
A list of supported formats for one end of a filter link.
Definition: formats.h:64
An instance of a filter.
Definition: avfilter.h:338
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
int height
Definition: frame.h:276
#define av_freep(p)
formats
Definition: signature.h:48
internal API functions
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition...
Definition: formats.c:410
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:265
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:284
for(j=16;j >0;--j)
AVFILTER_DEFINE_CLASS(showvolume)
CGA/EGA/VGA ROM font data.
simple arithmetic expression evaluator