Skip to content

Instantly share code, notes, and snippets.

Created January 31, 2013 12:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4682536 to your computer and use it in GitHub Desktop.
Save anonymous/4682536 to your computer and use it in GitHub Desktop.
stdin
diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c
index 21c9561..b71b422 100644
--- a/libavfilter/avf_showspectrum.c
+++ b/libavfilter/avf_showspectrum.c
@@ -38,7 +38,7 @@ typedef struct {
AVFilterBufferRef *outpicref;
int req_fullfilled;
int nb_display_channels;
- int compat; ///< use old up to 2 channels display mode
+ int combined; ///< use old-style combined channel display mode
int sliding; ///< 1 if sliding mode, 0 otherwise
int xpos; ///< x position (current column)
RDFTContext *rdft; ///< Real Discrete Fourier Transform context
@@ -56,7 +56,7 @@ static const AVOption showspectrum_options[] = {
{ "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x480"}, 0, 0, FLAGS },
{ "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x480"}, 0, 0, FLAGS },
{ "slide", "set sliding mode", OFFSET(sliding), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
- { "compat", "set compat mode", OFFSET(compat), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
+ { "combined", "set combined mode", OFFSET(combined), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
{ NULL },
};
@@ -96,7 +96,7 @@ static int query_formats(AVFilterContext *ctx)
AVFilterLink *inlink = ctx->inputs[0];
AVFilterLink *outlink = ctx->outputs[0];
static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE };
- static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE };
+ static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE };
/* set input audio formats */
formats = ff_make_format_list(sample_fmts);
@@ -133,7 +133,7 @@ static int config_output(AVFilterLink *outlink)
outlink->w = showspectrum->w;
outlink->h = showspectrum->h;
- h = showspectrum->compat ? outlink->h: outlink->h / inlink->channels;
+ h = showspectrum->combined ? outlink->h : outlink->h / inlink->channels;
/* RDFT window size (precision) according to the requested output frame height */
for (rdft_bits = 1; 1 << rdft_bits < 2 * h; rdft_bits++);
@@ -154,10 +154,7 @@ static int config_output(AVFilterLink *outlink)
for (i = 0; i < showspectrum->nb_display_channels; i++)
av_freep(&showspectrum->rdft_data[i]);
av_freep(&showspectrum->rdft_data);
- if (showspectrum->compat)
- showspectrum->nb_display_channels = FFMIN(inlink->channels, 2);
- else
- showspectrum->nb_display_channels = inlink->channels;
+ showspectrum->nb_display_channels = inlink->channels;
if (av_size_mult(sizeof(*showspectrum->rdft_data),
showspectrum->nb_display_channels * win_size, &rdft_size) < 0)
@@ -260,6 +257,9 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFilterBufferRef *insampl
/* complete RDFT window size? */
if (showspectrum->filled == win_size) {
+ /* channel height */
+ int h = showspectrum->combined ? outlink->h : outlink->h / showspectrum->nb_display_channels;
+
/* run RDFT on each samples set */
for (ch = 0; ch < showspectrum->nb_display_channels; ch++)
av_rdft_calc(showspectrum->rdft, showspectrum->rdft_data[ch]);
@@ -269,47 +269,67 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFilterBufferRef *insampl
#define IM(ch) showspectrum->rdft_data[ch][2*y + 1]
#define MAGNITUDE(re, im) sqrt((re)*(re) + (im)*(im))
- if (showspectrum->compat) {
- for (y = 0; y < outlink->h; y++) {
- // FIXME: bin[0] contains first and last bins
- uint8_t *p = outpicref->data[0] + (outlink->h - y - 1) * outpicref->linesize[0];
- int a = sqrt(w * MAGNITUDE(RE(0), IM(0)));
- int b = showspectrum->nb_display_channels > 1 ? sqrt(w * MAGNITUDE(RE(1), IM(1))) : a;
+ if (showspectrum->sliding) {
+ for (y = 0; y < outlink->h; y++) {
+ for (ch = 0; ch < 3; ch++) {
+ uint8_t *p = outpicref->data[ch] +
+ y * outpicref->linesize[ch];
+ memmove(p, p + 1, outlink->w - 1);
+ }
+ }
+ showspectrum->xpos = outlink->w - 1;
+ }
+
+ for (ch = 0; ch < showspectrum->nb_display_channels; ch++) {
+ float yf, uf, vf;
- if (showspectrum->sliding) {
- memmove(p, p + 3, (outlink->w - 1) * 3);
- p += (outlink->w - 1) * 3;
+ /* decide channel colors */
+ if (showspectrum->combined) {
+ yf = 1.0f / showspectrum->nb_display_channels;
+ uf = yf;
+ vf = yf;
} else {
- p += showspectrum->xpos * 3;
+ yf = 1.0f;
+ uf = 0.5f;
+ vf = 0.5f;
+ }
+ if (showspectrum->nb_display_channels >= 2) {
+ uf *= sin((2 * M_PI * ch) / showspectrum->nb_display_channels);
+ vf *= cos((2 * M_PI * ch) / showspectrum->nb_display_channels);
+ } else {
+ uf = 0.0f;
+ vf = 0.0f;
}
- a = FFMIN(a, 255);
- b = FFMIN(b, 255);
- p[0] = a;
- p[1] = b;
- p[2] = (a + b) / 2;
- }
- } else {
- int h = outlink->h / showspectrum->nb_display_channels;
-
- for (ch = 0; ch < showspectrum->nb_display_channels; ch++) {
- for (y = 0; y < h; y++) {
- uint8_t *p = outpicref->data[0] +
- (outlink->h - (ch * h + y) - 1) *
- outpicref->linesize[0];
- int a = sqrt(w * MAGNITUDE(RE(ch), IM(ch)));
-
- if (showspectrum->sliding) {
- memmove(p, p + 3, (outlink->w - 1) * 3);
- p += (outlink->w - 1) * 3;
- } else {
- p += showspectrum->xpos * 3;
- }
-
- p[0] = p[1] = p[2] = a;
+ for (y = 0; y < h; y++) {
+ int row = showspectrum->combined ? y : ch * h + y;
+ uint8_t *py = outpicref->data[0] +
+ (outlink->h - row - 1) * outpicref->linesize[0] +
+ showspectrum->xpos;
+ uint8_t *pu = outpicref->data[1] +
+ (outlink->h - row - 1) * outpicref->linesize[1] +
+ showspectrum->xpos;
+ uint8_t *pv = outpicref->data[2] +
+ (outlink->h - row - 1) * outpicref->linesize[2] +
+ showspectrum->xpos;
+
+ float a = sqrt(w * MAGNITUDE(RE(ch), IM(ch)));
+ int y = rint(a * yf);
+ int u = rint(a * uf);
+ int v = rint(a * vf);
+
+ if (ch == 0 || !showspectrum->combined) {
+ *py = FFMIN(y, 255);
+ *pu = FFMAX(0, FFMIN(128 + u, 255));
+ *pv = FFMAX(0, FFMIN(128 + v, 255));
+ } else {
+ *py = FFMIN(*py + y, 255);
+ *pu = FFMAX(0, FFMIN(*pu + u, 255));
+ *pv = FFMAX(0, FFMIN(*pv + v, 255));
}
}
}
+
outpicref->pts = insamples->pts +
av_rescale_q(showspectrum->consumed,
(AVRational){ 1, inlink->sample_rate },
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment