Go to the documentation of this file.
35 #if CONFIG_LIBFREETYPE
37 #include FT_FREETYPE_H
40 #if CONFIG_LIBFONTCONFIG
41 #include <fontconfig/fontconfig.h>
46 #define BASEFREQ 20.01523126408007475
47 #define ENDFREQ 20495.59681441799654
48 #define TLENGTH "384*tc/(384+tc*f)"
49 #define TLENGTH_MIN 0.001
50 #define VOLUME_MAX 100.0
51 #define FONTCOLOR "st(0, (midi(f)-59.5)/12);" \
52 "st(1, if(between(ld(0),0,1), 0.5-0.5*cos(2*PI*ld(0)), 0));" \
53 "r(1-ld(1)) + b(ld(1))"
54 #define CSCHEME "1|0.5|0|0|0.5|1"
56 #define OFFSET(x) offsetof(ShowCQTContext, x)
57 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
114 av_log(
s->ctx,
level,
"fft_time = %16.3f s.\n",
s->fft_time * 1e-6);
116 av_log(
s->ctx,
level,
"cqt_time = %16.3f s.\n",
s->cqt_time * 1e-6);
117 if (
s->process_cqt_time)
118 av_log(
s->ctx,
level,
"process_cqt_time = %16.3f s.\n",
s->process_cqt_time * 1e-6);
119 if (
s->update_sono_time)
120 av_log(
s->ctx,
level,
"update_sono_time = %16.3f s.\n",
s->update_sono_time * 1e-6);
122 av_log(
s->ctx,
level,
"alloc_time = %16.3f s.\n",
s->alloc_time * 1e-6);
124 av_log(
s->ctx,
level,
"bar_time = %16.3f s.\n",
s->bar_time * 1e-6);
126 av_log(
s->ctx,
level,
"axis_time = %16.3f s.\n",
s->axis_time * 1e-6);
128 av_log(
s->ctx,
level,
"sono_time = %16.3f s.\n",
s->sono_time * 1e-6);
130 plot_time =
s->fft_time +
s->cqt_time +
s->process_cqt_time +
s->update_sono_time
131 +
s->alloc_time +
s->bar_time +
s->axis_time +
s->sono_time;
133 av_log(
s->ctx,
level,
"plot_time = %16.3f s.\n", plot_time * 1e-6);
135 s->fft_time =
s->cqt_time =
s->process_cqt_time =
s->update_sono_time
136 =
s->alloc_time =
s->bar_time =
s->axis_time =
s->sono_time = 0;
138 if (
s->axis_frame && !
s->axis_frame->buf[0]) {
140 for (k = 0; k < 4; k++)
141 s->axis_frame->data[k] =
NULL;
148 for (k = 0; k <
s->cqt_len; k++)
166 double log_base, log_end;
167 double rcp_n = 1.0 / n;
177 for (x = 0; x < n; x++) {
178 double log_freq = log_base + (x + 0.5) * (log_end - log_base) * rcp_n;
179 freq[x] =
exp(log_freq);
186 double nan_replace,
int idx)
190 av_log(log_ctx,
level,
"[%d] %s is nan, setting it to %g.\n",
191 idx,
name, nan_replace);
194 av_log(log_ctx,
level,
"[%d] %s is too low (%g), setting it to %g.\n",
198 av_log(log_ctx,
level,
"[%d] %s it too high (%g), setting it to %g.\n",
207 double ret = 12200.0*12200.0 * (
f*
f*
f*
f);
208 ret /= (
f*
f + 20.6*20.6) * (
f*
f + 12200.0*12200.0) *
209 sqrt((
f*
f + 107.7*107.7) * (
f*
f + 737.9*737.9));
215 double ret = 12200.0*12200.0 * (
f*
f*
f);
216 ret /= (
f*
f + 20.6*20.6) * (
f*
f + 12200.0*12200.0) * sqrt(
f*
f + 158.5*158.5);
222 double ret = 12200.0*12200.0 * (
f*
f);
223 ret /= (
f*
f + 20.6*20.6) * (
f*
f + 12200.0*12200.0);
229 const char *func_names[] = {
"a_weighting",
"b_weighting",
"c_weighting",
NULL };
230 const char *sono_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
"bar_v",
NULL };
231 const char *bar_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
"sono_v",
NULL };
238 if (!
s->sono_v_buf || !
s->bar_v_buf)
247 for (x = 0; x <
s->cqt_len; x++) {
248 double vars[] = {
s->timeclamp,
s->timeclamp,
s->freq[x],
s->freq[x],
s->freq[x], 0.0 };
252 s->bar_v_buf[x] = vol * vol;
255 s->sono_v_buf[x] = vol * vol;
270 int len,
int fft_len)
273 for (k = 0; k <
len; k++) {
276 for (x = 0; x < coeffs[k].
len; x++) {
277 float u = coeffs[k].
val[x];
282 b.re +=
u *
src[j].re;
283 b.im +=
u *
src[j].im;
292 dst[k].
im =
r.re *
r.re +
r.im *
r.im;
298 const char *
var_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
NULL };
300 int rate =
s->ctx->inputs[0]->sample_rate;
301 int nb_cqt_coeffs = 0;
308 if (!(
s->coeffs =
av_calloc(
s->cqt_len,
sizeof(*
s->coeffs))))
311 for (k = 0; k <
s->cqt_len; k++) {
312 double vars[] = {
s->timeclamp,
s->timeclamp,
s->freq[k],
s->freq[k],
s->freq[k] };
313 double flen, center, tlength;
314 int start, end, m = k;
316 if (
s->freq[k] > 0.5 * rate)
321 flen = 8.0 *
s->fft_len / (tlength * rate);
322 center =
s->freq[k] *
s->fft_len / rate;
323 start =
FFMAX(0,
ceil(center - 0.5 * flen));
324 end =
FFMIN(
s->fft_len,
floor(center + 0.5 * flen));
326 s->coeffs[m].start = start & ~(
s->cqt_align - 1);
327 s->coeffs[m].len = (end | (
s->cqt_align - 1)) + 1 -
s->coeffs[m].start;
328 nb_cqt_coeffs +=
s->coeffs[m].len;
329 if (!(
s->coeffs[m].val =
av_calloc(
s->coeffs[m].len,
sizeof(*
s->coeffs[m].val))))
332 for (x = start; x <= end; x++) {
333 int sign = (x & 1) ? (-1) : 1;
334 double y = 2.0 *
M_PI * (x - center) * (1.0 / flen);
336 double w = 0.355768 + 0.487396 * cos(y) + 0.144232 * cos(2*y) + 0.012604 * cos(3*y);
337 w *= sign * (1.0 /
s->fft_len);
338 s->coeffs[m].val[x -
s->coeffs[m].start] =
w;
341 if (
s->permute_coeffs)
342 s->permute_coeffs(
s->coeffs[m].val,
s->coeffs[m].len);
352 for (k = 0; k <
s->cqt_len; k++)
372 memset(
out->data[0], 0,
out->linesize[0] *
h);
375 memset(
out->data[0], 16,
out->linesize[0] *
h);
376 memset(
out->data[1], 128,
out->linesize[1] * hh);
377 memset(
out->data[2], 128,
out->linesize[2] * hh);
379 memset(
out->data[3], 0,
out->linesize[3] *
h);
404 uint8_t *tmp_data[4] = {
NULL };
407 int tmp_w, tmp_h,
ret;
409 if ((
ret =
ff_load_image(tmp_data, tmp_linesize, &tmp_w, &tmp_h, &tmp_format,
410 s->axisfile,
s->ctx)) < 0)
419 tmp_format,
s->ctx)) < 0)
422 s->axis_frame->width =
s->width;
423 s->axis_frame->height =
s->axis_h;
434 static double midi(
void *p,
double f)
436 return log2(
f/440.0) * 12.0 + 69.0;
442 return lrint(x*255.0) << 16;
448 return lrint(x*255.0) << 8;
454 return lrint(x*255.0);
459 const char *
var_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
NULL };
460 const char *func_names[] = {
"midi",
"r",
"g",
"b",
NULL };
469 av_log(
s->ctx,
AV_LOG_WARNING,
"font axis rendering is not implemented in non-default frequency range,"
470 " please use axisfile option instead.\n");
474 if (
s->cqt_len == 1920)
486 double vars[] = {
s->timeclamp,
s->timeclamp, freq[
xs], freq[
xs], freq[
xs] };
490 int linesize =
tmp->linesize[0];
491 for (y = 0; y <
height; y++) {
492 data[linesize * y + 4 * x] =
r;
493 data[linesize * y + 4 * x + 1] =
g;
494 data[linesize * y + 4 * x + 2] =
b;
506 #if CONFIG_LIBFREETYPE
507 const char *str =
"EF G A BC D ";
509 int linesize =
tmp->linesize[0];
510 FT_Library lib =
NULL;
512 int font_width = 16, font_height = 32;
513 int font_repeat = font_width * 12;
514 int linear_hori_advance = font_width * 65536;
515 int non_monospace_warning = 0;
521 if (FT_Init_FreeType(&lib))
524 if (FT_New_Face(lib, fontfile, 0, &face))
527 if (FT_Set_Char_Size(face, 16*64, 0, 0, 0))
530 if (FT_Load_Char(face,
'A', FT_LOAD_RENDER))
533 if (FT_Set_Char_Size(face, 16*64 * linear_hori_advance / face->glyph->linearHoriAdvance, 0, 0, 0))
536 for (x = 0; x < 12; x++) {
537 int sx, sy, rx, bx, by, dx, dy;
542 if (FT_Load_Char(face, str[x], FT_LOAD_RENDER))
545 if (face->glyph->advance.x != font_width*64 && !non_monospace_warning) {
547 non_monospace_warning = 1;
550 sy = font_height - 8 - face->glyph->bitmap_top;
551 for (rx = 0; rx < 10; rx++) {
552 sx = rx * font_repeat + x * font_width + face->glyph->bitmap_left;
553 for (by = 0; by < face->glyph->bitmap.rows; by++) {
557 if (dy >= font_height)
560 for (bx = 0; bx < face->glyph->bitmap.width; bx++) {
566 data[dy*linesize+4*dx+3] = face->glyph->bitmap.buffer[by*face->glyph->bitmap.width+bx];
573 FT_Done_FreeType(lib);
579 FT_Done_FreeType(lib);
590 #if CONFIG_LIBFONTCONFIG
591 FcConfig *fontconfig;
592 FcPattern *pat, *best;
593 FcResult
result = FcResultMatch;
600 for (
i = 0; font[
i];
i++) {
605 if (!(fontconfig = FcInitLoadConfigAndFonts())) {
610 if (!(pat = FcNameParse((uint8_t *)font))) {
612 FcConfigDestroy(fontconfig);
616 FcDefaultSubstitute(pat);
618 if (!FcConfigSubstitute(fontconfig, pat, FcMatchPattern)) {
620 FcPatternDestroy(pat);
621 FcConfigDestroy(fontconfig);
625 best = FcFontMatch(fontconfig, pat, &
result);
626 FcPatternDestroy(pat);
629 if (!best ||
result != FcResultMatch) {
634 if (FcPatternGetString(best, FC_FILE, 0, (FcChar8 **)&filename) != FcResultMatch) {
642 FcPatternDestroy(best);
643 FcConfigDestroy(fontconfig);
654 const char *str =
"EF G A BC D ";
657 int linesize =
tmp->linesize[0];
661 uint8_t *startptr =
data + 4 * x;
662 for (
u = 0;
u < 12;
u++) {
663 for (v = 0; v <
height; v++) {
664 uint8_t *p = startptr + v * linesize +
height/2 * 4 *
u;
683 int default_font = 0;
708 s->axis_frame->width =
s->width;
709 s->axis_frame->height =
s->axis_h;
729 return expf(logf(v) /
g);
735 for (x = 0; x <
len; x++) {
745 for (x = 0; x <
len; x++) {
750 c[x].yuv.y =
cm[0][0] *
r +
cm[0][1] *
g +
cm[0][2] *
b;
751 c[x].yuv.u =
cm[1][0] *
r +
cm[1][1] *
g +
cm[1][2] *
b;
752 c[x].yuv.v =
cm[2][0] *
r +
cm[2][1] *
g +
cm[2][2] *
b;
759 int x, y,
w =
out->width;
760 float mul, ht, rcp_bar_h = 1.0f / bar_h, rcp_bar_t = 1.0f / bar_t;
761 uint8_t *v =
out->data[0], *lp;
762 int ls =
out->linesize[0];
764 for (y = 0; y < bar_h; y++) {
765 ht = (bar_h - y) * rcp_bar_h;
767 for (x = 0; x <
w; x++) {
773 mul = (
h[x] - ht) * rcp_h[x];
774 mul = (mul < bar_t) ? (mul * rcp_bar_t) : 1.0f;
783 #define DRAW_BAR_WITH_CHROMA(x) \
790 mul = (h[x] - ht) * rcp_h[x]; \
791 mul = (mul < bar_t) ? (mul * rcp_bar_t) : 1.0f; \
792 *lpy++ = lrintf(mul * c[x].yuv.y + 16.0f); \
793 *lpu++ = lrintf(mul * c[x].yuv.u + 128.0f); \
794 *lpv++ = lrintf(mul * c[x].yuv.v + 128.0f); \
798 #define DRAW_BAR_WITHOUT_CHROMA(x) \
803 mul = (h[x] - ht) * rcp_h[x]; \
804 mul = (mul < bar_t) ? (mul * rcp_bar_t) : 1.0f; \
805 *lpy++ = lrintf(mul * c[x].yuv.y + 16.0f); \
812 int x, y, yh,
w =
out->width;
813 float mul, ht, rcp_bar_h = 1.0f / bar_h, rcp_bar_t = 1.0f / bar_t;
814 uint8_t *vy =
out->data[0], *vu =
out->data[1], *vv =
out->data[2];
815 uint8_t *lpy, *lpu, *lpv;
816 int lsy =
out->linesize[0], lsu =
out->linesize[1], lsv =
out->linesize[2];
817 int fmt =
out->format;
819 for (y = 0; y < bar_h; y += 2) {
821 ht = (bar_h - y) * rcp_bar_h;
826 for (x = 0; x <
w; x += 2) {
831 for (x = 0; x <
w; x += 2) {
837 ht = (bar_h - (y+1)) * rcp_bar_h;
838 lpy = vy + (y+1) * lsy;
839 lpu = vu + (y+1) * lsu;
840 lpv = vv + (y+1) * lsv;
842 for (x = 0; x <
w; x += 2) {
847 for (x = 0; x <
w; x += 2) {
852 for (x = 0; x <
w; x += 2) {
863 float a, rcp_255 = 1.0f / 255.0f;
866 for (y = 0; y <
h; y++) {
867 lp =
out->data[0] + (off + y) *
out->linesize[0];
869 for (x = 0; x <
w; x++) {
874 }
else if (lpa[3] == 255) {
879 a = rcp_255 * lpa[3];
889 #define BLEND_WITH_CHROMA(c) \
892 *lpy = lrintf(c.yuv.y + 16.0f); \
893 *lpu = lrintf(c.yuv.u + 128.0f); \
894 *lpv = lrintf(c.yuv.v + 128.0f); \
895 } else if (255 == *lpaa) { \
900 float a = (1.0f/255.0f) * (*lpaa); \
901 *lpy = lrintf(a * (*lpay) + (1.0f - a) * (c.yuv.y + 16.0f)); \
902 *lpu = lrintf(a * (*lpau) + (1.0f - a) * (c.yuv.u + 128.0f)); \
903 *lpv = lrintf(a * (*lpav) + (1.0f - a) * (c.yuv.v + 128.0f)); \
905 lpy++; lpu++; lpv++; \
906 lpay++; lpau++; lpav++; lpaa++; \
909 #define BLEND_WITHOUT_CHROMA(c, alpha_inc) \
912 *lpy = lrintf(c.yuv.y + 16.0f); \
913 } else if (255 == *lpaa) { \
916 float a = (1.0f/255.0f) * (*lpaa); \
917 *lpy = lrintf(a * (*lpay) + (1.0f - a) * (c.yuv.y + 16.0f)); \
920 lpay++; lpaa += alpha_inc; \
923 #define BLEND_CHROMA2(c) \
925 if (!lpaa[0] && !lpaa[1]) { \
926 *lpu = lrintf(c.yuv.u + 128.0f); \
927 *lpv = lrintf(c.yuv.v + 128.0f); \
928 } else if (255 == lpaa[0] && 255 == lpaa[1]) { \
929 *lpu = *lpau; *lpv = *lpav; \
931 float a0 = (0.5f/255.0f) * lpaa[0]; \
932 float a1 = (0.5f/255.0f) * lpaa[1]; \
933 float b = 1.0f - a0 - a1; \
934 *lpu = lrintf(a0 * lpau[0] + a1 * lpau[1] + b * (c.yuv.u + 128.0f)); \
935 *lpv = lrintf(a0 * lpav[0] + a1 * lpav[1] + b * (c.yuv.v + 128.0f)); \
937 lpau += 2; lpav += 2; lpaa++; lpu++; lpv++; \
940 #define BLEND_CHROMA2x2(c) \
942 if (!lpaa[0] && !lpaa[1] && !lpaa[lsaa] && !lpaa[lsaa+1]) { \
943 *lpu = lrintf(c.yuv.u + 128.0f); \
944 *lpv = lrintf(c.yuv.v + 128.0f); \
945 } else if (255 == lpaa[0] && 255 == lpaa[1] && \
946 255 == lpaa[lsaa] && 255 == lpaa[lsaa+1]) { \
947 *lpu = *lpau; *lpv = *lpav; \
949 float a0 = (0.25f/255.0f) * lpaa[0]; \
950 float a1 = (0.25f/255.0f) * lpaa[1]; \
951 float a2 = (0.25f/255.0f) * lpaa[lsaa]; \
952 float a3 = (0.25f/255.0f) * lpaa[lsaa+1]; \
953 float b = 1.0f - a0 - a1 - a2 - a3; \
954 *lpu = lrintf(a0 * lpau[0] + a1 * lpau[1] + a2 * lpau[lsau] + a3 * lpau[lsau+1] \
955 + b * (c.yuv.u + 128.0f)); \
956 *lpv = lrintf(a0 * lpav[0] + a1 * lpav[1] + a2 * lpav[lsav] + a3 * lpav[lsav+1] \
957 + b * (c.yuv.v + 128.0f)); \
959 lpau += 2; lpav += 2; lpaa++; lpu++; lpv++; \
966 uint8_t *vy =
out->data[0], *vu =
out->data[1], *vv =
out->data[2];
967 uint8_t *vay = axis->
data[0], *vau = axis->
data[1], *vav = axis->
data[2], *vaa = axis->
data[3];
968 int lsy =
out->linesize[0], lsu =
out->linesize[1], lsv =
out->linesize[2];
970 uint8_t *lpy, *lpu, *lpv, *lpay, *lpau, *lpav, *lpaa;
972 for (y = 0; y <
h; y += 2) {
974 lpy = vy + (off + y) * lsy;
975 lpu = vu + (offh + yh) * lsu;
976 lpv = vv + (offh + yh) * lsv;
977 lpay = vay + y * lsay;
978 lpau = vau + y * lsau;
979 lpav = vav + y * lsav;
980 lpaa = vaa + y * lsaa;
982 for (x = 0; x <
w; x += 2) {
987 for (x = 0; x <
w; x += 2) {
993 for (x = 0; x <
w; x += 2) {
1000 lpy = vy + (off + y + 1) * lsy;
1001 lpu = vu + (off + y + 1) * lsu;
1002 lpv = vv + (off + y + 1) * lsv;
1003 lpay = vay + (y + 1) * lsay;
1004 lpau = vau + (y + 1) * lsau;
1005 lpav = vav + (y + 1) * lsav;
1006 lpaa = vaa + (y + 1) * lsaa;
1008 for (x = 0; x <
w; x += 2) {
1013 for (x = 0; x <
w; x += 2) {
1019 for (x = 0; x <
w; x += 2) {
1037 for (y = 0; y <
h; y++) {
1038 memcpy(
out->data[0] + (off + y) *
out->linesize[0],
1042 for (
i = 1;
i < nb_planes;
i++) {
1044 for (y = 0; y <
h; y += inc) {
1046 memcpy(
out->data[
i] + (offh + yh) *
out->linesize[
i],
1057 for (x = 0; x <
w; x++) {
1067 uint8_t *lpy = sono->
data[0] + idx * sono->
linesize[0];
1068 uint8_t *lpu = sono->
data[1] + idx * sono->
linesize[1];
1069 uint8_t *lpv = sono->
data[2] + idx * sono->
linesize[2];
1071 for (x = 0; x <
w; x += 2) {
1072 *lpy++ =
lrintf(
c[x].yuv.y + 16.0f);
1073 *lpu++ =
lrintf(
c[x].yuv.u + 128.0f);
1074 *lpv++ =
lrintf(
c[x].yuv.v + 128.0f);
1075 *lpy++ =
lrintf(
c[x+1].yuv.y + 16.0f);
1077 *lpu++ =
lrintf(
c[x+1].yuv.u + 128.0f);
1078 *lpv++ =
lrintf(
c[x+1].yuv.v + 128.0f);
1086 if (!
s->sono_count) {
1087 for (x = 0; x <
s->cqt_len; x++) {
1088 s->h_buf[x] =
s->bar_v_buf[x] * 0.5f * (
s->cqt_result[x].re +
s->cqt_result[x].im);
1090 if (
s->fcount > 1) {
1091 float rcp_fcount = 1.0f /
s->fcount;
1092 for (x = 0; x <
s->width; x++) {
1094 for (
i = 0;
i <
s->fcount;
i++)
1095 h +=
s->h_buf[
s->fcount * x +
i];
1096 s->h_buf[x] = rcp_fcount *
h;
1099 for (x = 0; x <
s->width; x++) {
1101 s->rcp_h_buf[x] = 1.0f / (
s->h_buf[x] + 0.0001f);
1105 for (x = 0; x <
s->cqt_len; x++) {
1106 s->cqt_result[x].re *=
s->sono_v_buf[x];
1107 s->cqt_result[x].im *=
s->sono_v_buf[x];
1110 if (
s->fcount > 1) {
1111 float rcp_fcount = 1.0f /
s->fcount;
1112 for (x = 0; x <
s->width; x++) {
1114 for (
i = 0;
i <
s->fcount;
i++) {
1115 result.re +=
s->cqt_result[
s->fcount * x +
i].re;
1116 result.im +=
s->cqt_result[
s->fcount * x +
i].im;
1118 s->cqt_result[x].re = rcp_fcount *
result.re;
1119 s->cqt_result[x].im = rcp_fcount *
result.im;
1126 yuv_from_cqt(
s->c_buf,
s->cqt_result,
s->sono_g,
s->width,
s->cmatrix,
s->cscheme_v);
1133 int64_t last_time, cur_time;
1135 #define UPDATE_TIME(t) \
1136 cur_time = av_gettime_relative(); \
1137 t += cur_time - last_time; \
1138 last_time = cur_time
1142 memcpy(
s->fft_input,
s->fft_data,
s->fft_len *
sizeof(*
s->fft_data));
1143 if (
s->attack_data) {
1145 for (k = 0; k <
s->remaining_fill_max; k++) {
1146 s->fft_input[
s->fft_len/2+k].re *=
s->attack_data[k];
1147 s->fft_input[
s->fft_len/2+k].im *=
s->attack_data[k];
1154 s->cqt_calc(
s->cqt_result,
s->fft_result,
s->coeffs,
s->cqt_len,
s->fft_len);
1161 s->update_sono(
s->sono_frame,
s->c_buf,
s->sono_idx);
1165 if (!
s->sono_count) {
1171 out->colorspace =
s->csp;
1175 s->draw_bar(
out,
s->h_buf,
s->rcp_h_buf,
s->c_buf,
s->bar_h,
s->bar_t);
1180 s->draw_axis(
out,
s->axis_frame,
s->c_buf,
s->bar_h);
1185 s->draw_sono(
out,
s->sono_frame,
s->bar_h +
s->axis_h,
s->sono_idx);
1189 s->sono_count = (
s->sono_count + 1) %
s->count;
1191 s->sono_idx = (
s->sono_idx +
s->sono_h - 1) %
s->sono_h;
1207 kr = 0.299; kb = 0.114;
break;
1209 kr = 0.2126; kb = 0.0722;
break;
1211 kr = 0.30; kb = 0.11;
break;
1213 kr = 0.212; kb = 0.087;
break;
1215 kr = 0.2627; kb = 0.0593;
break;
1219 s->cmatrix[0][0] = 219.0 * kr;
1220 s->cmatrix[0][1] = 219.0 * kg;
1221 s->cmatrix[0][2] = 219.0 * kb;
1222 s->cmatrix[1][0] = -112.0 * kr / (1.0 - kb);
1223 s->cmatrix[1][1] = -112.0 * kg / (1.0 - kb);
1224 s->cmatrix[1][2] = 112.0;
1225 s->cmatrix[2][0] = 112.0;
1226 s->cmatrix[2][1] = -112.0 * kg / (1.0 - kr);
1227 s->cmatrix[2][2] = -112.0 * kb / (1.0 - kr);
1235 if (sscanf(
s->cscheme,
" %f | %f | %f | %f | %f | %f %1s", &
s->cscheme_v[0],
1236 &
s->cscheme_v[1], &
s->cscheme_v[2], &
s->cscheme_v[3], &
s->cscheme_v[4],
1237 &
s->cscheme_v[5], tail) != 6)
1240 for (k = 0; k < 6; k++)
1241 if (
isnan(
s->cscheme_v[k]) ||
s->cscheme_v[k] < 0.0f ||
s->cscheme_v[k] > 1.0f)
1259 if (
s->width != 1920 ||
s->height != 1080) {
1268 if (
s->axis_h < 0) {
1269 s->axis_h =
s->width / 60;
1272 if (
s->bar_h >= 0 &&
s->sono_h >= 0)
1273 s->axis_h =
s->height -
s->bar_h -
s->sono_h;
1274 if (
s->bar_h >= 0 &&
s->sono_h < 0)
1275 s->axis_h =
FFMIN(
s->axis_h,
s->height -
s->bar_h);
1276 if (
s->bar_h < 0 &&
s->sono_h >= 0)
1277 s->axis_h =
FFMIN(
s->axis_h,
s->height -
s->sono_h);
1281 s->bar_h = (
s->height -
s->axis_h) / 2;
1285 s->bar_h =
s->height -
s->sono_h -
s->axis_h;
1289 s->sono_h =
s->height -
s->axis_h -
s->bar_h;
1291 if ((
s->width & 1) || (
s->height & 1) || (
s->bar_h & 1) || (
s->axis_h & 1) || (
s->sono_h & 1) ||
1292 (
s->bar_h < 0) || (
s->axis_h < 0) || (
s->sono_h < 0) || (
s->bar_h >
s->height) ||
1293 (
s->axis_h >
s->height) || (
s->sono_h >
s->height) || (
s->bar_h +
s->axis_h +
s->sono_h !=
s->height)) {
1301 }
while(
s->fcount *
s->width < 1920 &&
s->fcount < 10);
1360 outlink->
w =
s->width;
1361 outlink->
h =
s->height;
1368 s->bar_h,
s->axis_h,
s->sono_h);
1370 s->cqt_len =
s->width *
s->fcount;
1378 s->fft_len = 1 <<
s->fft_bits;
1382 s->fft_data =
av_calloc(
s->fft_len,
sizeof(*
s->fft_data));
1386 if (!
s->fft_ctx || !
s->fft_data || !
s->fft_result || !
s->cqt_result)
1389 s->remaining_fill_max =
s->fft_len / 2;
1390 if (
s->attack > 0.0) {
1393 s->remaining_fill_max =
FFMIN(
s->remaining_fill_max,
ceil(
inlink->sample_rate *
s->attack));
1395 if (!
s->attack_data)
1398 for (k = 0; k <
s->remaining_fill_max; k++) {
1399 double y =
M_PI * k / (
inlink->sample_rate *
s->attack);
1400 s->attack_data[k] = 0.355768 + 0.487396 * cos(y) + 0.144232 * cos(2*y) + 0.012604 * cos(3*y);
1406 s->permute_coeffs =
NULL;
1429 }
else if (
s->axisfile) {
1457 if (!
s->h_buf || !
s->rcp_h_buf || !
s->c_buf)
1463 s->remaining_fill =
s->remaining_fill_max;
1464 s->remaining_frac = 0;
1466 s->step = (
int)(
s->step_frac.num /
s->step_frac.den);
1467 s->step_frac.num %=
s->step_frac.den;
1468 if (
s->step_frac.num) {
1470 inlink->sample_rate,
s->step,
s->step_frac.num,
s->step_frac.den);
1473 inlink->sample_rate,
s->step);
1485 int remaining,
step,
ret, x,
i, j, m, got_frame = 0;
1490 while (
s->remaining_fill <
s->remaining_fill_max) {
1491 memset(&
s->fft_data[
s->fft_len/2 +
s->remaining_fill_max -
s->remaining_fill], 0,
sizeof(*
s->fft_data) *
s->remaining_fill);
1496 step =
s->step + (
s->step_frac.num +
s->remaining_frac) /
s->step_frac.den;
1497 s->remaining_frac = (
s->step_frac.num +
s->remaining_frac) %
s->step_frac.den;
1498 for (x = 0; x < (
s->fft_len/2 +
s->remaining_fill_max -
step); x++)
1499 s->fft_data[x] =
s->fft_data[x+
step];
1500 s->remaining_fill +=
step;
1504 out->pts =
s->next_pts;
1513 audio_data = (
float*) insamples->
data[0];
1517 j =
s->fft_len/2 +
s->remaining_fill_max -
s->remaining_fill;
1518 if (remaining >=
s->remaining_fill) {
1519 for (m = 0; m <
s->remaining_fill; m++) {
1520 s->fft_data[j+m].re = audio_data[2*(
i+m)];
1521 s->fft_data[j+m].im = audio_data[2*(
i+m)+1];
1528 remaining -=
s->remaining_fill;
1542 step =
s->step + (
s->step_frac.num +
s->remaining_frac) /
s->step_frac.den;
1543 s->remaining_frac = (
s->step_frac.num +
s->remaining_frac) %
s->step_frac.den;
1544 for (m = 0; m <
s->fft_len/2 +
s->remaining_fill_max -
step; m++)
1545 s->fft_data[m] =
s->fft_data[m+
step];
1546 s->remaining_fill =
step;
1548 for (m = 0; m < remaining; m++) {
1549 s->fft_data[j+m].re = audio_data[2*(
i+m)];
1550 s->fft_data[j+m].im = audio_data[2*(
i+m)+1];
1552 s->remaining_fill -= remaining;
1573 nb_samples =
s->step + (
s->step_frac.num +
s->remaining_frac) /
s->step_frac.den;
1611 .description =
NULL_IF_CONFIG_SMALL(
"Convert input audio to a CQT (Constant/Clamped Q Transform) spectrum video output."),
1619 .priv_class = &showcqt_class,
static void error(const char *err)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
A list of supported channel layouts.
#define AV_LOG_WARNING
Something somehow does not look correct.
const AVFilter ff_avf_showcqt
#define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
AVPixelFormat
Pixel format.
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
static void draw_axis_yuv(AVFrame *out, AVFrame *axis, const ColorFloat *c, int off)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static void draw_bar_yuv(AVFrame *out, const float *h, const float *rcp_h, const ColorFloat *c, int bar_h, float bar_t)
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
#define AV_CHANNEL_LAYOUT_STEREO
#define u(width, name, range_min, range_max)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
static enum AVSampleFormat sample_fmts[]
enum MovChannelLayoutTag * layouts
#define AVERROR_EOF
End of file.
@ AV_OPT_TYPE_VIDEO_RATE
offset must point to AVRational
static const char *const var_names[]
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
static int init_cscheme(ShowCQTContext *s)
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
This structure describes decoded (raw) audio or video data.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
#define FILTER_QUERY_FUNC(func)
static uint8_t half(int a, int b)
#define BLEND_WITH_CHROMA(c)
#define AV_LOG_VERBOSE
Detailed information.
static double c_weighting(void *p, double f)
const char * name
Filter name.
static int render_default_font(AVFrame *tmp)
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
static void draw_axis_rgb(AVFrame *out, AVFrame *axis, const ColorFloat *c, int off)
A link between two filters.
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
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.
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
static double a_weighting(void *p, double f)
static double val(void *priv, double ch)
static av_cold void uninit(AVFilterContext *ctx)
static av_always_inline float scale(float x, float s)
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
A filter pad used for either input or output.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static __device__ float ceil(float a)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static const uint16_t mask[17]
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
#define BLEND_WITHOUT_CHROMA(c, alpha_inc)
#define DRAW_BAR_WITHOUT_CHROMA(x)
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
static void init_colormatrix(ShowCQTContext *s)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
static __device__ float floor(float a)
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable; if left to 0/0,...
static enum AVPixelFormat pix_fmts[]
@ AV_TX_FLOAT_FFT
Standard complex to complex FFT with sample data type of AVComplexFloat, AVComplexDouble or AVComplex...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
#define BLEND_CHROMA2x2(c)
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
#define FILTER_INPUTS(array)
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static double clip_with_log(void *log_ctx, const char *name, double val, double min, double max, double nan_replace, int idx)
#define xs(width, name, var, subs,...)
and forward the result(frame or status change) to the corresponding input. If nothing is possible
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
static av_cold int init(AVFilterContext *ctx)
static const uint8_t vars[2][12]
static int render_freetype(ShowCQTContext *s, AVFrame *tmp, char *fontfile)
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
static __device__ float sqrtf(float a)
static void rgb_from_cqt(ColorFloat *c, const AVComplexFloat *v, float g, int len, float cscheme[6])
static const AVFilterPad showcqt_inputs[]
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
static AVFrame * alloc_frame_empty(enum AVPixelFormat format, int w, int h)
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
static int init_axis_from_file(ShowCQTContext *s)
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static const AVFilterPad showcqt_outputs[]
An AVChannelLayout holds information about the channel layout of audio data.
static void process_cqt(ShowCQTContext *s)
static float calculate_gamma(float v, float g)
static int init_axis_color(ShowCQTContext *s, AVFrame *tmp, int half)
int format
agreed upon media format
static int init_axis_from_font(ShowCQTContext *s)
static AVRational av_make_q(int num, int den)
Create an AVRational.
static void update_sono_rgb(AVFrame *sono, const ColorFloat *c, int idx)
static int query_formats(AVFilterContext *ctx)
int ff_load_image(uint8_t *data[4], int linesize[4], int *w, int *h, enum AVPixelFormat *pix_fmt, const char *filename, void *log_ctx)
Load image from filename and put the resulting image in data.
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
AVFilterContext * src
source filter
AVFilterFormatsConfig incfg
Lists of supported formats / etc.
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
static int init_volume(ShowCQTContext *s)
FF_FILTER_FORWARD_WANTED(outlink, inlink)
static void yuv_from_cqt(ColorFloat *c, const AVComplexFloat *v, float gamma, int len, float cm[3][3], float cscheme[6])
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
@ AVCOL_SPC_SMPTE240M
derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries
static enum AVPixelFormat convert_axis_pixel_format(enum AVPixelFormat format)
static double * create_freq_table(double base, double end, int n)
int nb_samples
number of audio samples (per channel) described by this frame
static double b_weighting(void *p, double f)
const uint8_t avpriv_vga16_font[4096]
#define i(width, name, range_min, range_max)
static double b_func(void *p, double x)
static double r_func(void *p, double x)
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
int w
agreed upon image width
#define av_malloc_array(a, b)
AVSampleFormat
Audio sample formats.
static av_always_inline float cbrtf(float x)
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
const char * name
Pad name.
static void draw_bar_rgb(AVFrame *out, const float *h, const float *rcp_h, const ColorFloat *c, int bar_h, float bar_t)
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
void * av_calloc(size_t nmemb, size_t size)
static void cqt_calc(AVComplexFloat *dst, const AVComplexFloat *src, const Coeffs *coeffs, int len, int fft_len)
static int activate(AVFilterContext *ctx)
static void common_uninit(ShowCQTContext *s)
static int plot_cqt(AVFilterContext *ctx, AVFrame **frameout)
static int config_output(AVFilterLink *outlink)
static const AVOption showcqt_options[]
int h
agreed upon image height
@ AVCOL_SPC_FCC
FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
static double midi(void *p, double f)
static int init_cqt(ShowCQTContext *s)
static void update_sono_yuv(AVFrame *sono, const ColorFloat *c, int idx)
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
void ff_showcqt_init_x86(ShowCQTContext *s)
static double g_func(void *p, double x)
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
static const uint16_t channel_layouts[7]
#define FILTER_OUTPUTS(array)
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
AVFILTER_DEFINE_CLASS(showcqt)
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
int ff_scale_image(uint8_t *dst_data[4], int dst_linesize[4], int dst_w, int dst_h, enum AVPixelFormat dst_pix_fmt, uint8_t *const src_data[4], int src_linesize[4], int src_w, int src_h, enum AVPixelFormat src_pix_fmt, void *log_ctx)
Scale image using libswscale.
static void draw_sono(AVFrame *out, AVFrame *sono, int off, int idx)
#define DRAW_BAR_WITH_CHROMA(x)
static int init_axis_empty(ShowCQTContext *s)
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
static int render_fontconfig(ShowCQTContext *s, AVFrame *tmp, char *font)