mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-02-04 06:08:26 +02:00
avfilter/avf_showwaves: New p2p mode for showwaves filter
Reviewed-by: Paul B Mahol <onemda@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
a53a107a2f
commit
6f3e15af84
@ -10701,6 +10701,9 @@ Draw a point for each sample.
|
|||||||
|
|
||||||
@item line
|
@item line
|
||||||
Draw a vertical line for each sample.
|
Draw a vertical line for each sample.
|
||||||
|
|
||||||
|
@item p2p
|
||||||
|
Draw a point for each sample and a line between them.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
Default value is @code{point}.
|
Default value is @code{point}.
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
enum ShowWavesMode {
|
enum ShowWavesMode {
|
||||||
MODE_POINT,
|
MODE_POINT,
|
||||||
MODE_LINE,
|
MODE_LINE,
|
||||||
|
MODE_P2P,
|
||||||
MODE_NB,
|
MODE_NB,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -43,6 +44,7 @@ typedef struct {
|
|||||||
int w, h;
|
int w, h;
|
||||||
AVRational rate;
|
AVRational rate;
|
||||||
int buf_idx;
|
int buf_idx;
|
||||||
|
int16_t *buf_idy; /* y coordinate of previous sample for each channel */
|
||||||
AVFrame *outpicref;
|
AVFrame *outpicref;
|
||||||
int req_fullfilled;
|
int req_fullfilled;
|
||||||
int n;
|
int n;
|
||||||
@ -59,6 +61,7 @@ static const AVOption showwaves_options[] = {
|
|||||||
{ "mode", "select display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_POINT}, 0, MODE_NB-1, FLAGS, "mode"},
|
{ "mode", "select display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_POINT}, 0, MODE_NB-1, FLAGS, "mode"},
|
||||||
{ "point", "draw a point for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_POINT}, .flags=FLAGS, .unit="mode"},
|
{ "point", "draw a point for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_POINT}, .flags=FLAGS, .unit="mode"},
|
||||||
{ "line", "draw a line for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_LINE}, .flags=FLAGS, .unit="mode"},
|
{ "line", "draw a line for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_LINE}, .flags=FLAGS, .unit="mode"},
|
||||||
|
{ "p2p", "draw a line between samples", 0, AV_OPT_TYPE_CONST, {.i64=MODE_P2P}, .flags=FLAGS, .unit="mode"},
|
||||||
{ "n", "set how many samples to show in the same point", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS },
|
{ "n", "set how many samples to show in the same point", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS },
|
||||||
{ "rate", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
|
{ "rate", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
|
||||||
{ "r", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
|
{ "r", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
|
||||||
@ -72,6 +75,7 @@ static av_cold void uninit(AVFilterContext *ctx)
|
|||||||
ShowWavesContext *showwaves = ctx->priv;
|
ShowWavesContext *showwaves = ctx->priv;
|
||||||
|
|
||||||
av_frame_free(&showwaves->outpicref);
|
av_frame_free(&showwaves->outpicref);
|
||||||
|
av_freep(&showwaves->buf_idy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int query_formats(AVFilterContext *ctx)
|
static int query_formats(AVFilterContext *ctx)
|
||||||
@ -113,11 +117,16 @@ static int config_output(AVFilterLink *outlink)
|
|||||||
AVFilterContext *ctx = outlink->src;
|
AVFilterContext *ctx = outlink->src;
|
||||||
AVFilterLink *inlink = ctx->inputs[0];
|
AVFilterLink *inlink = ctx->inputs[0];
|
||||||
ShowWavesContext *showwaves = ctx->priv;
|
ShowWavesContext *showwaves = ctx->priv;
|
||||||
|
int nb_channels = inlink->channels;
|
||||||
|
|
||||||
if (!showwaves->n)
|
if (!showwaves->n)
|
||||||
showwaves->n = FFMAX(1, ((double)inlink->sample_rate / (showwaves->w * av_q2d(showwaves->rate))) + 0.5);
|
showwaves->n = FFMAX(1, ((double)inlink->sample_rate / (showwaves->w * av_q2d(showwaves->rate))) + 0.5);
|
||||||
|
|
||||||
showwaves->buf_idx = 0;
|
showwaves->buf_idx = 0;
|
||||||
|
if (!(showwaves->buf_idy = av_mallocz_array(nb_channels, sizeof(*showwaves->buf_idy)))) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Could not allocate showwaves buffer\n");
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
outlink->w = showwaves->w;
|
outlink->w = showwaves->w;
|
||||||
outlink->h = showwaves->h;
|
outlink->h = showwaves->h;
|
||||||
outlink->sample_aspect_ratio = (AVRational){1,1};
|
outlink->sample_aspect_ratio = (AVRational){1,1};
|
||||||
@ -132,13 +141,18 @@ static int config_output(AVFilterLink *outlink)
|
|||||||
|
|
||||||
inline static int push_frame(AVFilterLink *outlink)
|
inline static int push_frame(AVFilterLink *outlink)
|
||||||
{
|
{
|
||||||
|
AVFilterContext *ctx = outlink->src;
|
||||||
|
AVFilterLink *inlink = ctx->inputs[0];
|
||||||
ShowWavesContext *showwaves = outlink->src->priv;
|
ShowWavesContext *showwaves = outlink->src->priv;
|
||||||
int ret;
|
int nb_channels = inlink->channels;
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
if ((ret = ff_filter_frame(outlink, showwaves->outpicref)) >= 0)
|
if ((ret = ff_filter_frame(outlink, showwaves->outpicref)) >= 0)
|
||||||
showwaves->req_fullfilled = 1;
|
showwaves->req_fullfilled = 1;
|
||||||
showwaves->outpicref = NULL;
|
showwaves->outpicref = NULL;
|
||||||
showwaves->buf_idx = 0;
|
showwaves->buf_idx = 0;
|
||||||
|
for (i = 0; i <= nb_channels; i++)
|
||||||
|
showwaves->buf_idy[i] = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,8 +221,22 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
|
|||||||
*(outpicref->data[0] + showwaves->buf_idx + k * linesize) += x;
|
*(outpicref->data[0] + showwaves->buf_idx + k * linesize) += x;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MODE_P2P:
|
||||||
|
if (h >= 0 && h < outlink->h) {
|
||||||
|
*(outpicref->data[0] + showwaves->buf_idx + h * linesize) += x;
|
||||||
|
if (showwaves->buf_idy[j] && h != showwaves->buf_idy[j]) {
|
||||||
|
int start = showwaves->buf_idy[j], end = av_clip(h, 0, outlink->h-1);
|
||||||
|
if (start > end)
|
||||||
|
FFSWAP(int16_t, start, end);
|
||||||
|
for (k = start + 1; k < end; k++)
|
||||||
|
*(outpicref->data[0] + showwaves->buf_idx + k * linesize) += x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* store current y coordinate for this channel */
|
||||||
|
showwaves->buf_idy[j] = h;
|
||||||
|
}
|
||||||
|
|
||||||
showwaves->sample_count_mod++;
|
showwaves->sample_count_mod++;
|
||||||
if (showwaves->sample_count_mod == n) {
|
if (showwaves->sample_count_mod == n) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user