Created
January 31, 2013 12:29
-
-
Save anonymous/4682536 to your computer and use it in GitHub Desktop.
stdin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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