50 enum ColorMode {
CHANNEL,
INTENSITY,
RAINBOW,
MORELAND,
NEBULAE,
FIRE,
FIERY,
FRUIT,
COOL,
MAGMA,
GREEN,
VIRIDIS,
PLASMA,
CIVIDIS,
TERRAIN,
NB_CLMODES };
103 #define OFFSET(x) offsetof(ShowSpectrumContext, x)
104 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
189 { 0.13, .03587126228984074, .1573300977624594, -.02548747583751842 },
190 { 0.30, .18572281794568020, .1772436246393981, .17475554840414750 },
191 { 0.60, .28184980583656130, -.1593064119945782, .47132074554608920 },
192 { 0.73, .65830621175547810, -.3716070802232764, .24352759331252930 },
193 { 0.78, .76318535758242900, -.4307467689263783, .16866496622310430 },
194 { 0.91, .95336363636363640, -.2045454545454546, .03313636363636363 },
198 { 0.13, 44/256., (189-128)/256., (138-128)/256. },
199 { 0.25, 29/256., (186-128)/256., (119-128)/256. },
200 { 0.38, 119/256., (194-128)/256., (53-128)/256. },
201 { 0.60, 111/256., (73-128)/256., (59-128)/256. },
202 { 0.73, 205/256., (19-128)/256., (149-128)/256. },
203 { 0.86, 135/256., (83-128)/256., (200-128)/256. },
204 { 1, 73/256., (95-128)/256., (225-128)/256. }},
206 { 0, 44/256., (181-128)/256., (112-128)/256. },
207 { 0.13, 126/256., (177-128)/256., (106-128)/256. },
208 { 0.25, 164/256., (163-128)/256., (109-128)/256. },
209 { 0.38, 200/256., (140-128)/256., (120-128)/256. },
210 { 0.60, 201/256., (117-128)/256., (141-128)/256. },
211 { 0.73, 177/256., (103-128)/256., (165-128)/256. },
212 { 0.86, 136/256., (100-128)/256., (183-128)/256. },
213 { 1, 68/256., (117-128)/256., (203-128)/256. }},
215 { 0, 10/256., (134-128)/256., (132-128)/256. },
216 { 0.23, 21/256., (137-128)/256., (130-128)/256. },
217 { 0.45, 35/256., (134-128)/256., (134-128)/256. },
218 { 0.57, 51/256., (130-128)/256., (139-128)/256. },
219 { 0.67, 104/256., (116-128)/256., (162-128)/256. },
220 { 0.77, 120/256., (105-128)/256., (188-128)/256. },
221 { 0.87, 140/256., (105-128)/256., (188-128)/256. },
225 { 0.23, 44/256., (132-128)/256., (127-128)/256. },
226 { 0.45, 62/256., (116-128)/256., (140-128)/256. },
227 { 0.57, 75/256., (105-128)/256., (152-128)/256. },
228 { 0.67, 95/256., (91-128)/256., (166-128)/256. },
229 { 0.77, 126/256., (74-128)/256., (172-128)/256. },
230 { 0.87, 164/256., (73-128)/256., (162-128)/256. },
234 { 0.23, 36/256., (116-128)/256., (163-128)/256. },
235 { 0.45, 52/256., (102-128)/256., (200-128)/256. },
236 { 0.57, 116/256., (84-128)/256., (196-128)/256. },
237 { 0.67, 157/256., (67-128)/256., (181-128)/256. },
238 { 0.77, 193/256., (40-128)/256., (155-128)/256. },
239 { 0.87, 221/256., (101-128)/256., (134-128)/256. },
243 { 0.20, 29/256., (136-128)/256., (119-128)/256. },
244 { 0.30, 60/256., (119-128)/256., (90-128)/256. },
245 { 0.40, 85/256., (91-128)/256., (85-128)/256. },
246 { 0.50, 116/256., (70-128)/256., (105-128)/256. },
247 { 0.60, 151/256., (50-128)/256., (146-128)/256. },
248 { 0.70, 191/256., (63-128)/256., (178-128)/256. },
249 { 1, 98/256., (80-128)/256., (221-128)/256. }},
256 { 0.10, 23/256., (175-128)/256., (120-128)/256. },
257 { 0.23, 43/256., (158-128)/256., (144-128)/256. },
258 { 0.35, 85/256., (138-128)/256., (179-128)/256. },
259 { 0.48, 96/256., (128-128)/256., (189-128)/256. },
260 { 0.64, 128/256., (103-128)/256., (214-128)/256. },
261 { 0.92, 205/256., (80-128)/256., (152-128)/256. },
269 { 0.10, 0x39/255., (0x9D -128)/255., (0x8F -128)/255. },
270 { 0.23, 0x5C/255., (0x9A -128)/255., (0x68 -128)/255. },
271 { 0.35, 0x69/255., (0x93 -128)/255., (0x57 -128)/255. },
272 { 0.48, 0x76/255., (0x88 -128)/255., (0x4B -128)/255. },
273 { 0.64, 0x8A/255., (0x72 -128)/255., (0x4F -128)/255. },
274 { 0.80, 0xA3/255., (0x50 -128)/255., (0x66 -128)/255. },
275 { 1, 0xCC/255., (0x2F -128)/255., (0x87 -128)/255. }},
278 { 0.10, 0x27/255., (0xC2 -128)/255., (0x82 -128)/255. },
279 { 0.58, 0x5B/255., (0x9A -128)/255., (0xAE -128)/255. },
280 { 0.70, 0x89/255., (0x44 -128)/255., (0xAB -128)/255. },
281 { 0.80, 0xB4/255., (0x2B -128)/255., (0x9E -128)/255. },
282 { 0.91, 0xD2/255., (0x38 -128)/255., (0x92 -128)/255. },
286 { 0.20, 0x28/255., (0x98 -128)/255., (0x6F -128)/255. },
287 { 0.50, 0x48/255., (0x95 -128)/255., (0x74 -128)/255. },
288 { 0.63, 0x69/255., (0x84 -128)/255., (0x7F -128)/255. },
289 { 0.76, 0x89/255., (0x75 -128)/255., (0x84 -128)/255. },
290 { 0.90, 0xCE/255., (0x35 -128)/255., (0x95 -128)/255. },
295 { 0.60, 1, -.5, -.5 },
296 { 0.85, 1, -.5, .5 },
307 for (
i = 0;
i <
s->nb_display_channels;
i++)
312 for (
i = 0;
i <
s->nb_display_channels;
i++)
317 for (
i = 0;
i <
s->nb_display_channels;
i++)
321 if (
s->fft_scratch) {
322 for (
i = 0;
i <
s->nb_display_channels;
i++)
326 if (
s->color_buffer) {
327 for (
i = 0;
i <
s->nb_display_channels;
i++)
333 for (
i = 0;
i <
s->nb_display_channels;
i++)
340 for (
i = 0;
i <
s->nb_display_channels;
i++)
381 const float *window_func_lut =
s->window_func_lut;
383 const int ch = jobnr;
389 for (
n = 0;
n <
s->win_size;
n++) {
390 s->fft_data[
ch][
n].re = p[
n] * window_func_lut[
n];
391 s->fft_data[
ch][
n].im = 0;
395 float theta, phi, psi,
a,
b,
S,
c;
400 int M =
s->win_size / 2;
402 phi = 2.f *
M_PI * (
s->stop -
s->start) / (
float)
inlink->sample_rate / (
M - 1);
403 theta = 2.f *
M_PI *
s->start / (float)
inlink->sample_rate;
410 for (
int n =
M;
n <
L;
n++) {
415 for (
int n =
L -
N;
n <
L;
n++) {
420 for (
int n = 0;
n <
N;
n++) {
421 g[
n].re =
s->fft_data[
ch][
n].re;
422 g[
n].im =
s->fft_data[
ch][
n].im;
425 for (
int n =
N;
n <
L;
n++) {
430 for (
int n = 0;
n <
N;
n++) {
431 psi =
n * theta +
n *
n / 2.f * phi;
446 for (
int n = 0;
n <
L;
n++) {
459 for (
int k = 0; k <
M; k++) {
460 psi = k * k / 2.f * phi;
463 a =
c *
g[k].re -
S *
g[k].im;
464 b =
S *
g[k].re +
c *
g[k].im;
465 s->fft_data[
ch][k].re =
a;
466 s->fft_data[
ch][k].im =
b;
485 for (
i = 0; txt[
i];
i++) {
489 for (char_y = font_height - 1; char_y >= 0; char_y--) {
492 if (font[txt[
i] * font_height + font_height - 1 - char_y] &
mask)
493 p[char_y] = ~p[char_y];
499 for (char_y = 0; char_y < font_height; char_y++) {
501 if (font[txt[
i] * font_height + char_y] &
mask)
512 float *yf,
float *uf,
float *vf)
517 *yf = 256.0f /
s->nb_display_channels;
518 switch (
s->color_mode) {
557 if (
s->nb_display_channels > 1) {
558 *uf *= 0.5f *
sinf((2 *
M_PI *
ch) /
s->nb_display_channels +
M_PI *
s->rotation);
559 *vf *= 0.5f *
cosf((2 *
M_PI *
ch) /
s->nb_display_channels +
M_PI *
s->rotation);
569 *uf *=
s->saturation;
570 *vf *=
s->saturation;
574 float yf,
float uf,
float vf,
578 const int cm =
s->color_mode;
623 else if (log10(seconds) > 6)
625 else if (log10(seconds) > 3)
650 const float hz_per_bin = max_freq / num_bins;
651 const float freq = hz_per_bin * bin;
652 const float scaled_freq =
log_scale(freq + 1, 21, max_freq) - 1;
654 return num_bins * scaled_freq / max_freq;
675 const float hz_per_bin = max_freq / num_bins;
676 const float freq = hz_per_bin * bin;
677 const float scaled_freq =
inv_log_scale(freq + 1, 21, max_freq) - 1;
679 return num_bins * scaled_freq / max_freq;
687 int ch, y, x = 0, sz =
s->orientation ==
VERTICAL ?
s->w :
s->h;
689 float spp =
samples / (float)sz;
692 char chlayout_str[128];
699 drawtext(
s->outpicref, 2, outlink->
h - 10,
"CREATED BY LIBAVFILTER", 0);
700 drawtext(
s->outpicref, outlink->
w - 2 - strlen(text) * 10, outlink->
h - 10, text, 0);
702 char *text =
av_asprintf(
"Zoom: %d Hz - %d Hz",
s->start,
s->stop);
703 drawtext(
s->outpicref, outlink->
w - 2 - strlen(text) * 10, 3, text, 0);
709 dst =
s->outpicref->data[0] + (
s->start_y - 1) *
s->outpicref->linesize[0] +
s->start_x - 1;
710 for (x = 0; x <
s->w + 1; x++)
712 dst =
s->outpicref->data[0] + (
s->start_y +
s->h) *
s->outpicref->linesize[0] +
s->start_x - 1;
713 for (x = 0; x <
s->w + 1; x++)
715 for (y = 0; y <
s->h + 2; y++) {
716 dst =
s->outpicref->data[0] + (y +
s->start_y - 1) *
s->outpicref->linesize[0];
717 dst[
s->start_x - 1] = 200;
718 dst[
s->start_x +
s->w] = 200;
721 int h =
s->mode ==
SEPARATE ?
s->h /
s->nb_display_channels :
s->h;
722 int hh =
s->mode ==
SEPARATE ? -(
s->h %
s->nb_display_channels) + 1 : 1;
723 for (
ch = 0;
ch < (
s->mode ==
SEPARATE ?
s->nb_display_channels : 1);
ch++) {
724 for (y = 0; y <
h; y += 20) {
725 dst =
s->outpicref->data[0] + (
s->start_y +
h * (
ch + 1) - y - hh) *
s->outpicref->linesize[0];
726 dst[
s->start_x - 2] = 200;
727 dst[
s->start_x +
s->w + 1] = 200;
729 for (y = 0; y <
h; y += 40) {
730 dst =
s->outpicref->data[0] + (
s->start_y +
h * (
ch + 1) - y - hh) *
s->outpicref->linesize[0];
731 dst[
s->start_x - 3] = 200;
732 dst[
s->start_x +
s->w + 2] = 200;
734 dst =
s->outpicref->data[0] + (
s->start_y - 2) *
s->outpicref->linesize[0] +
s->start_x;
735 for (x = 0; x <
s->w; x+=40)
737 dst =
s->outpicref->data[0] + (
s->start_y - 3) *
s->outpicref->linesize[0] +
s->start_x;
738 for (x = 0; x <
s->w; x+=80)
740 dst =
s->outpicref->data[0] + (
s->h +
s->start_y + 1) *
s->outpicref->linesize[0] +
s->start_x;
741 for (x = 0; x <
s->w; x+=40) {
744 dst =
s->outpicref->data[0] + (
s->h +
s->start_y + 2) *
s->outpicref->linesize[0] +
s->start_x;
745 for (x = 0; x <
s->w; x+=80) {
748 for (y = 0; y <
h; y += 40) {
749 float range =
s->stop ?
s->stop -
s->start :
inlink->sample_rate / 2;
751 float hertz =
s->start + bin * range / (float)(1 << (
int)ceil(
log2(
h)));
761 drawtext(
s->outpicref,
s->start_x - 8 * strlen(units) - 4,
h * (
ch + 1) +
s->start_y - y - 4 - hh, units, 0);
766 for (x = 0; x <
s->w &&
s->single_pic; x+=80) {
767 float seconds = x * spp /
inlink->sample_rate;
770 drawtext(
s->outpicref,
s->start_x + x - 4 * strlen(units),
s->h +
s->start_y + 6, units, 0);
771 drawtext(
s->outpicref,
s->start_x + x - 4 * strlen(units),
s->start_y - 12, units, 0);
775 drawtext(
s->outpicref, outlink->
w / 2 - 4 * 4, outlink->
h -
s->start_y / 2,
"TIME", 0);
776 drawtext(
s->outpicref,
s->start_x / 7, outlink->
h / 2 - 14 * 4,
"FREQUENCY (Hz)", 1);
778 int w =
s->mode ==
SEPARATE ?
s->w /
s->nb_display_channels :
s->w;
779 for (y = 0; y <
s->h; y += 20) {
780 dst =
s->outpicref->data[0] + (
s->start_y + y) *
s->outpicref->linesize[0];
781 dst[
s->start_x - 2] = 200;
782 dst[
s->start_x +
s->w + 1] = 200;
784 for (y = 0; y <
s->h; y += 40) {
785 dst =
s->outpicref->data[0] + (
s->start_y + y) *
s->outpicref->linesize[0];
786 dst[
s->start_x - 3] = 200;
787 dst[
s->start_x +
s->w + 2] = 200;
789 for (
ch = 0;
ch < (
s->mode ==
SEPARATE ?
s->nb_display_channels : 1);
ch++) {
790 dst =
s->outpicref->data[0] + (
s->start_y - 2) *
s->outpicref->linesize[0] +
s->start_x +
w *
ch;
791 for (x = 0; x <
w; x+=40)
793 dst =
s->outpicref->data[0] + (
s->start_y - 3) *
s->outpicref->linesize[0] +
s->start_x +
w *
ch;
794 for (x = 0; x <
w; x+=80)
796 dst =
s->outpicref->data[0] + (
s->h +
s->start_y + 1) *
s->outpicref->linesize[0] +
s->start_x +
w *
ch;
797 for (x = 0; x <
w; x+=40) {
800 dst =
s->outpicref->data[0] + (
s->h +
s->start_y + 2) *
s->outpicref->linesize[0] +
s->start_x +
w *
ch;
801 for (x = 0; x <
w; x+=80) {
804 for (x = 0; x <
w - 79; x += 80) {
805 float range =
s->stop ?
s->stop -
s->start :
inlink->sample_rate / 2;
807 float hertz =
s->start + bin * range / (float)(1 << (
int)ceil(
log2(
w)));
817 drawtext(
s->outpicref,
s->start_x - 4 * strlen(units) + x +
w *
ch,
s->start_y - 12, units, 0);
818 drawtext(
s->outpicref,
s->start_x - 4 * strlen(units) + x +
w *
ch,
s->h +
s->start_y + 6, units, 0);
822 for (y = 0; y <
s->h &&
s->single_pic; y+=40) {
823 float seconds = y * spp /
inlink->sample_rate;
826 drawtext(
s->outpicref,
s->start_x - 8 * strlen(units) - 4,
s->start_y + y - 4, units, 0);
829 drawtext(
s->outpicref,
s->start_x / 7, outlink->
h / 2 - 4 * 4,
"TIME", 1);
830 drawtext(
s->outpicref, outlink->
w / 2 - 14 * 4, outlink->
h -
s->start_y / 2,
"FREQUENCY (Hz)", 0);
833 for (
ch = 0;
ch < (multi ?
s->nb_display_channels : 1);
ch++) {
834 int h = multi ?
s->h /
s->nb_display_channels :
s->h;
836 for (y = 0; y <
h; y++) {
837 float out[3] = { 0., 127.5, 127.5};
840 for (chn = 0; chn < (
s->mode ==
SEPARATE ? 1 :
s->nb_display_channels); chn++) {
842 int channel = (multi) ?
s->nb_display_channels -
ch - 1 : chn;
851 memset(
s->outpicref->data[0]+(
s->start_y +
h * (
ch + 1) - y - 1) *
s->outpicref->linesize[0] +
s->w +
s->start_x + 20, av_clip_uint8(
out[0]), 10);
852 memset(
s->outpicref->data[1]+(
s->start_y +
h * (
ch + 1) - y - 1) *
s->outpicref->linesize[1] +
s->w +
s->start_x + 20, av_clip_uint8(
out[1]), 10);
853 memset(
s->outpicref->data[2]+(
s->start_y +
h * (
ch + 1) - y - 1) *
s->outpicref->linesize[2] +
s->w +
s->start_x + 20, av_clip_uint8(
out[2]), 10);
856 for (y = 0;
ch == 0 && y <
h; y +=
h / 10) {
865 drawtext(
s->outpicref,
s->w +
s->start_x + 35,
s->start_y + y - 5, text, 0);
876 float *magnitudes =
s->magnitudes[
ch];
877 float *phases =
s->phases[
ch];
896 a = av_clipf(
a, 0, 1);
899 a = av_clipf(sqrtf(
a), 0, 1);
905 a = av_clipf(sqrtf(sqrtf(
a)), 0, 1);
908 a = av_clipf(
powf(
a, 0.20), 0, 1);
911 a = 1.f +
log10f(av_clipf(
a, 1e-6, 1)) / 6.f;
923 const int h =
s->orientation ==
VERTICAL ?
s->channel_height :
s->channel_width;
924 const int ch = jobnr;
932 for (y = 0; y <
h; y++) {
934 float *
out = &
s->color_buffer[
ch][3 * row];
947 const int h =
s->orientation ==
VERTICAL ?
s->channel_height :
s->channel_width;
948 const int ch = jobnr;
956 for (y = 0; y <
h && yy <
h; yy++) {
959 float delta = pos1 - pos0;
964 for (
float j = pos0; j < pos1 && y + j - pos0 <
h; j++) {
965 float row = (
s->mode ==
COMBINED) ? y + j - pos0 :
ch *
h + y + j - pos0;
967 float lerpfrac = (j - pos0) /
delta;
982 int i, fft_bits,
h,
w;
992 if (
s->stop &&
s->stop <=
s->start) {
997 if (!strcmp(
ctx->filter->name,
"showspectrumpic"))
1005 s->start_x = (log10(
inlink->sample_rate) + 1) * 25;
1007 outlink->
w +=
s->start_x * 2;
1008 outlink->
h +=
s->start_y * 2;
1013 s->channel_height =
h;
1014 s->channel_width =
w;
1018 for (fft_bits = 1; 1 << fft_bits < 2 *
h; fft_bits++);
1021 for (fft_bits = 1; 1 << fft_bits < 2 *
w; fft_bits++);
1024 s->win_size = 1 << fft_bits;
1025 s->buf_size =
s->win_size << !!
s->stop;
1042 if (fft_bits !=
s->fft_bits) {
1045 s->fft_bits = fft_bits;
1050 for (
i = 0;
i <
s->nb_display_channels;
i++) {
1060 s->nb_display_channels =
inlink->channels;
1061 for (
i = 0;
i <
s->nb_display_channels;
i++) {
1067 "The window size might be too high.\n");
1073 "The window size might be too high.\n");
1078 s->magnitudes =
av_calloc(
s->nb_display_channels,
sizeof(*
s->magnitudes));
1081 for (
i = 0;
i <
s->nb_display_channels;
i++) {
1083 if (!
s->magnitudes[
i])
1087 s->phases =
av_calloc(
s->nb_display_channels,
sizeof(*
s->phases));
1090 for (
i = 0;
i <
s->nb_display_channels;
i++) {
1097 s->color_buffer =
av_calloc(
s->nb_display_channels,
sizeof(*
s->color_buffer));
1098 if (!
s->color_buffer)
1100 for (
i = 0;
i <
s->nb_display_channels;
i++) {
1102 if (!
s->color_buffer[
i])
1106 s->fft_data =
av_calloc(
s->nb_display_channels,
sizeof(*
s->fft_data));
1109 s->fft_scratch =
av_calloc(
s->nb_display_channels,
sizeof(*
s->fft_scratch));
1110 if (!
s->fft_scratch)
1112 for (
i = 0;
i <
s->nb_display_channels;
i++) {
1113 s->fft_data[
i] =
av_calloc(
s->buf_size,
sizeof(**
s->fft_data));
1114 if (!
s->fft_data[
i])
1117 s->fft_scratch[
i] =
av_calloc(
s->buf_size,
sizeof(**
s->fft_scratch));
1118 if (!
s->fft_scratch[
i])
1123 s->window_func_lut =
1125 sizeof(*
s->window_func_lut));
1126 if (!
s->window_func_lut)
1129 if (
s->overlap == 1)
1130 s->overlap = overlap;
1131 s->hop_size = (1.f -
s->overlap) *
s->win_size;
1132 if (
s->hop_size < 1) {
1137 for (
s->win_scale = 0,
i = 0; i < s->win_size;
i++) {
1138 s->win_scale +=
s->window_func_lut[
i] *
s->window_func_lut[
i];
1140 s->win_scale = 1.f / sqrtf(
s->win_scale);
1144 s->outpicref = outpicref =
1149 for (
i = 0;
i < outlink->
h;
i++) {
1150 memset(outpicref->
data[0] +
i * outpicref->
linesize[0], 0, outlink->
w);
1151 memset(outpicref->
data[1] +
i * outpicref->
linesize[1], 128, outlink->
w);
1152 memset(outpicref->
data[2] +
i * outpicref->
linesize[2], 128, outlink->
w);
1156 if (!
s->single_pic &&
s->legend)
1160 if ((
s->orientation ==
VERTICAL &&
s->xpos >=
s->w) ||
1166 s->auto_frame_rate.den *=
s->w;
1168 s->auto_frame_rate.den *=
s->h;
1169 if (!
s->single_pic && strcmp(
s->rate_str,
"auto")) {
1174 s->frame_rate =
s->auto_frame_rate;
1182 sizeof(*
s->combine_buffer));
1186 sizeof(*
s->combine_buffer));
1190 s->w,
s->h,
s->win_size);
1199 #define RE(y, ch) s->fft_data[ch][y].re
1200 #define IM(y, ch) s->fft_data[ch][y].im
1201 #define MAGNITUDE(y, ch) hypotf(RE(y, ch), IM(y, ch))
1202 #define PHASE(y, ch) atan2f(IM(y, ch), RE(y, ch))
1207 const double w =
s->win_scale * (
s->scale ==
LOG ?
s->win_scale : 1);
1209 const float f =
s->gain *
w;
1210 const int ch = jobnr;
1211 float *magnitudes =
s->magnitudes[
ch];
1213 for (y = 0; y <
h; y++)
1222 const int h =
s->orientation ==
VERTICAL ?
s->h :
s->w;
1223 const int ch = jobnr;
1224 float *phases =
s->phases[
ch];
1227 for (y = 0; y <
h; y++)
1235 const double w =
s->win_scale * (
s->scale ==
LOG ?
s->win_scale : 1);
1237 const float f =
s->gain *
w;
1239 for (
ch = 0;
ch <
s->nb_display_channels;
ch++) {
1240 float *magnitudes =
s->magnitudes[
ch];
1242 for (y = 0; y <
h; y++)
1251 for (
ch = 0;
ch <
s->nb_display_channels;
ch++) {
1252 float *magnitudes =
s->magnitudes[
ch];
1254 for (y = 0; y <
h; y++)
1255 magnitudes[y] *= scale;
1263 for (y = 0; y <
size; y++) {
1264 s->combine_buffer[3 * y ] = 0;
1265 s->combine_buffer[3 * y + 1] = 127.5;
1266 s->combine_buffer[3 * y + 2] = 127.5;
1284 for (y = 0; y < z * 3; y++) {
1285 for (x = 0; x <
s->nb_display_channels; x++) {
1286 s->combine_buffer[y] +=
s->color_buffer[x][y];
1295 for (y = 0; y <
s->h; y++) {
1298 memmove(p, p + 1,
s->w - 1);
1302 }
else if (
s->sliding ==
RSCROLL) {
1304 for (y = 0; y <
s->h; y++) {
1307 memmove(p + 1, p,
s->w - 1);
1316 for (y = 0; y <
s->h; y++) {
1317 *p =
lrintf(av_clipf(
s->combine_buffer[3 * y +
plane], 0, 255));
1324 for (y = 1; y <
s->h; y++) {
1331 }
else if (
s->sliding ==
RSCROLL) {
1333 for (y =
s->h - 1; y >= 1; y--) {
1344 for (x = 0; x <
s->w; x++) {
1345 *p =
lrintf(av_clipf(
s->combine_buffer[3 * x +
plane], 0, 255));
1355 if (
s->orientation ==
VERTICAL &&
s->xpos >=
s->w)
1359 if (!
s->single_pic && (
s->sliding !=
FULLFRAME ||
s->xpos == 0)) {
1360 if (
s->old_pts < outpicref->
pts) {
1365 for (y = 0; y < 10; y++) {
1366 memset(
s->outpicref->data[0] + outlink->
w / 2 - 4 *
s->old_len +
1367 (outlink->
h -
s->start_y / 2 - 20 + y) *
s->outpicref->linesize[0], 0, 10 *
s->old_len);
1370 outlink->
w / 2 - 4 * strlen(units),
1371 outlink->
h -
s->start_y / 2 - 20,
1374 for (y = 0; y < 10 *
s->old_len; y++) {
1375 memset(
s->outpicref->data[0] +
s->start_x / 7 + 20 +
1376 (outlink->
h / 2 - 4 *
s->old_len + y) *
s->outpicref->linesize[0], 0, 10);
1379 s->start_x / 7 + 20,
1380 outlink->
h / 2 - 4 * strlen(units),
1383 s->old_len = strlen(units);
1386 s->old_pts = outpicref->
pts;
1397 #if CONFIG_SHOWSPECTRUM_FILTER
1428 fin->
pts =
s->pts +
s->consumed;
1429 s->consumed +=
s->hop_size;
1457 s->xpos > 0 &&
s->outpicref) {
1461 for (
int i = 0;
i < outlink->
h;
i++) {
1462 memset(
s->outpicref->data[0] +
i *
s->outpicref->linesize[0] +
s->xpos, 0, outlink->
w -
s->xpos);
1463 memset(
s->outpicref->data[1] +
i *
s->outpicref->linesize[1] +
s->xpos, 128, outlink->
w -
s->xpos);
1464 memset(
s->outpicref->data[2] +
i *
s->outpicref->linesize[2] +
s->xpos, 128, outlink->
w -
s->xpos);
1467 for (
int i =
s->xpos; i < outlink->
h;
i++) {
1468 memset(
s->outpicref->data[0] +
i *
s->outpicref->linesize[0], 0, outlink->
w);
1469 memset(
s->outpicref->data[1] +
i *
s->outpicref->linesize[1], 128, outlink->
w);
1470 memset(
s->outpicref->data[2] +
i *
s->outpicref->linesize[2], 128, outlink->
w);
1473 s->outpicref->pts +=
s->consumed;
1474 pts =
s->outpicref->pts;
1476 s->outpicref =
NULL;
1494 static const AVFilterPad showspectrum_inputs[] = {
1502 static const AVFilterPad showspectrum_outputs[] = {
1512 .
name =
"showspectrum",
1517 .
inputs = showspectrum_inputs,
1518 .
outputs = showspectrum_outputs,
1520 .priv_class = &showspectrum_class,
1523 #endif // CONFIG_SHOWSPECTRUM_FILTER
1525 #if CONFIG_SHOWSPECTRUMPIC_FILTER
1527 static const AVOption showspectrumpic_options[] = {
1595 static int showspectrumpic_request_frame(
AVFilterLink *outlink)
1606 int x = 0, sz =
s->orientation ==
VERTICAL ?
s->w :
s->h;
1610 spf =
s->win_size * (
samples / ((
s->win_size * sz) * ceil(
samples / (
float)(
s->win_size * sz))));
1611 spf =
FFMAX(1, spf);
1613 spb = (
samples / (spf * sz)) * spf;
1628 if (ret < s->win_size) {
1629 for (
ch = 0;
ch <
s->nb_display_channels;
ch++) {
1631 (
s->win_size -
ret) *
sizeof(
float));
1639 if (consumed >= spb) {
1646 for (
ch = 0;
ch <
s->nb_display_channels;
ch++)
1647 memset(
s->magnitudes[
ch], 0,
h *
sizeof(
float));
1652 s->outpicref->pts = 0;
1658 s->outpicref =
NULL;
1675 static const AVFilterPad showspectrumpic_inputs[] = {
1679 .filter_frame = showspectrumpic_filter_frame,
1684 static const AVFilterPad showspectrumpic_outputs[] = {
1689 .request_frame = showspectrumpic_request_frame,
1695 .
name =
"showspectrumpic",
1696 .description =
NULL_IF_CONFIG_SMALL(
"Convert input audio to a spectrum video output single picture."),
1700 .
inputs = showspectrumpic_inputs,
1701 .
outputs = showspectrumpic_outputs,
1702 .priv_class = &showspectrumpic_class,
1706 #endif // CONFIG_SHOWSPECTRUMPIC_FILTER