Commit 7c10e32a authored by Nicolas George's avatar Nicolas George

lavfi/avf_showspectrum: add full frame sliding mode.

parent ec33df60
...@@ -10687,8 +10687,19 @@ the "Video size" section in the ffmpeg-utils manual. Default value is ...@@ -10687,8 +10687,19 @@ the "Video size" section in the ffmpeg-utils manual. Default value is
@code{640x512}. @code{640x512}.
@item slide @item slide
Specify if the spectrum should slide along the window. Default value is Specify how the spectrum should slide along the window.
@code{0}.
It accepts the following values:
@table @samp
@item replace
the samples start again on the left when they reach the right
@item scroll
the samples scroll from right to left
@item fullframe
frames are only produced when the samples reach the right
@end table
Default value is @code{replace}.
@item mode @item mode
Specify display mode. Specify display mode.
......
...@@ -38,6 +38,7 @@ enum DisplayMode { COMBINED, SEPARATE, NB_MODES }; ...@@ -38,6 +38,7 @@ enum DisplayMode { COMBINED, SEPARATE, NB_MODES };
enum DisplayScale { LINEAR, SQRT, CBRT, LOG, NB_SCALES }; enum DisplayScale { LINEAR, SQRT, CBRT, LOG, NB_SCALES };
enum ColorMode { CHANNEL, INTENSITY, NB_CLMODES }; enum ColorMode { CHANNEL, INTENSITY, NB_CLMODES };
enum WindowFunc { WFUNC_NONE, WFUNC_HANN, WFUNC_HAMMING, WFUNC_BLACKMAN, NB_WFUNC }; enum WindowFunc { WFUNC_NONE, WFUNC_HANN, WFUNC_HAMMING, WFUNC_BLACKMAN, NB_WFUNC };
enum SlideMode { REPLACE, SCROLL, FULLFRAME, NB_SLIDES };
typedef struct { typedef struct {
const AVClass *class; const AVClass *class;
...@@ -66,7 +67,10 @@ typedef struct { ...@@ -66,7 +67,10 @@ typedef struct {
static const AVOption showspectrum_options[] = { static const AVOption showspectrum_options[] = {
{ "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS }, { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS },
{ "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS }, { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS },
{ "slide", "set sliding mode", OFFSET(sliding), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS }, { "slide", "set sliding mode", OFFSET(sliding), AV_OPT_TYPE_INT, {.i64 = 0}, 0, NB_SLIDES, FLAGS, "slide" },
{ "replace", "replace old colums with new", 0, AV_OPT_TYPE_CONST, {.i64=REPLACE}, 0, 0, FLAGS, "slide" },
{ "scroll", "scroll from right to left", 0, AV_OPT_TYPE_CONST, {.i64=SCROLL}, 0, 0, FLAGS, "slide" },
{ "fullframe", "return full frames", 0, AV_OPT_TYPE_CONST, {.i64=FULLFRAME}, 0, 0, FLAGS, "slide" },
{ "mode", "set channel display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=COMBINED}, COMBINED, NB_MODES-1, FLAGS, "mode" }, { "mode", "set channel display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=COMBINED}, COMBINED, NB_MODES-1, FLAGS, "mode" },
{ "combined", "combined mode", 0, AV_OPT_TYPE_CONST, {.i64=COMBINED}, 0, 0, FLAGS, "mode" }, { "combined", "combined mode", 0, AV_OPT_TYPE_CONST, {.i64=COMBINED}, 0, 0, FLAGS, "mode" },
{ "separate", "separate mode", 0, AV_OPT_TYPE_CONST, {.i64=SEPARATE}, 0, 0, FLAGS, "mode" }, { "separate", "separate mode", 0, AV_OPT_TYPE_CONST, {.i64=SEPARATE}, 0, 0, FLAGS, "mode" },
...@@ -244,6 +248,8 @@ static int config_output(AVFilterLink *outlink) ...@@ -244,6 +248,8 @@ static int config_output(AVFilterLink *outlink)
s->xpos = 0; s->xpos = 0;
outlink->frame_rate = av_make_q(inlink->sample_rate, win_size); outlink->frame_rate = av_make_q(inlink->sample_rate, win_size);
if (s->sliding == FULLFRAME)
outlink->frame_rate.den *= outlink->w;
inlink->min_samples = inlink->max_samples = inlink->partial_buf_size = inlink->min_samples = inlink->max_samples = inlink->partial_buf_size =
win_size; win_size;
...@@ -257,27 +263,27 @@ static int config_output(AVFilterLink *outlink) ...@@ -257,27 +263,27 @@ static int config_output(AVFilterLink *outlink)
return 0; return 0;
} }
inline static int push_frame(AVFilterLink *outlink)
{
ShowSpectrumContext *s = outlink->src->priv;
s->xpos++;
if (s->xpos >= outlink->w)
s->xpos = 0;
s->req_fullfilled = 1;
return ff_filter_frame(outlink, av_frame_clone(s->outpicref));
}
static int request_frame(AVFilterLink *outlink) static int request_frame(AVFilterLink *outlink)
{ {
ShowSpectrumContext *s = outlink->src->priv; ShowSpectrumContext *s = outlink->src->priv;
AVFilterLink *inlink = outlink->src->inputs[0]; AVFilterLink *inlink = outlink->src->inputs[0];
unsigned i;
int ret; int ret;
s->req_fullfilled = 0; s->req_fullfilled = 0;
do { do {
ret = ff_request_frame(inlink); ret = ff_request_frame(inlink);
if (ret == AVERROR_EOF && s->sliding == FULLFRAME && s->xpos > 0 &&
s->outpicref) {
for (i = 0; i < outlink->h; i++) {
memset(s->outpicref->data[0] + i * s->outpicref->linesize[0] + s->xpos, 0, outlink->w - s->xpos);
memset(s->outpicref->data[1] + i * s->outpicref->linesize[1] + s->xpos, 128, outlink->w - s->xpos);
memset(s->outpicref->data[2] + i * s->outpicref->linesize[2] + s->xpos, 128, outlink->w - s->xpos);
}
ret = ff_filter_frame(outlink, s->outpicref);
s->outpicref = NULL;
s->req_fullfilled = 1;
}
} while (!s->req_fullfilled && ret >= 0); } while (!s->req_fullfilled && ret >= 0);
return ret; return ret;
...@@ -439,7 +445,7 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples) ...@@ -439,7 +445,7 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
} }
/* copy to output */ /* copy to output */
if (s->sliding) { if (s->sliding == SCROLL) {
for (plane = 0; plane < 3; plane++) { for (plane = 0; plane < 3; plane++) {
for (y = 0; y < outlink->h; y++) { for (y = 0; y < outlink->h; y++) {
uint8_t *p = outpicref->data[plane] + uint8_t *p = outpicref->data[plane] +
...@@ -459,10 +465,18 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples) ...@@ -459,10 +465,18 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
} }
} }
outpicref->pts = insamples->pts; if (s->sliding != FULLFRAME || s->xpos == 0)
ret = push_frame(outlink); outpicref->pts = insamples->pts;
if (ret < 0)
return ret; s->xpos++;
if (s->xpos >= outlink->w)
s->xpos = 0;
if (s->sliding != FULLFRAME || s->xpos == 0) {
s->req_fullfilled = 1;
ret = ff_filter_frame(outlink, av_frame_clone(s->outpicref));
if (ret < 0)
return ret;
}
return win_size; return win_size;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment