[FFmpeg-devel] [PATCH] New p2p mode for showwaves filter
Paul B Mahol
onemda at gmail.com
Mon Aug 4 09:34:57 CEST 2014
On Mon, Aug 4, 2014 at 9:24 AM, mrskman <mrskman at gmail.com> wrote:
> New patch attached.
>
> Thank you.
>
> ---
> doc/filters.texi | 3 +++
> libavfilter/avf_showwaves.c | 33 ++++++++++++++++++++++++++++++++-
> 2 files changed, 35 insertions(+), 1 deletions(-)
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index a7919a3..145acbf 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -10698,6 +10698,9 @@ Draw a point for each sample.
>
> @item line
> Draw a vertical line for each sample.
> +
> + at item p2p
> +Draw a point for each sample and a line between them.
> @end table
>
> Default value is @code{point}.
> diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c
> index 0b45bd0..e6158b2 100644
> --- a/libavfilter/avf_showwaves.c
> +++ b/libavfilter/avf_showwaves.c
> @@ -35,6 +35,7 @@
> enum ShowWavesMode {
> MODE_POINT,
> MODE_LINE,
> + MODE_P2P,
> MODE_NB,
> };
>
> @@ -43,6 +44,7 @@ typedef struct {
> int w, h;
> AVRational rate;
> int buf_idx;
> + int *buf_idy; /* y coordinate of previous sample for each channel
> */
> AVFrame *outpicref;
> int req_fullfilled;
> 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"},
> { "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"},
> + { "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 },
> { "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 },
> @@ -72,6 +75,8 @@ static av_cold void uninit(AVFilterContext *ctx)
> ShowWavesContext *showwaves = ctx->priv;
>
> av_frame_free(&showwaves->outpicref);
> + if (showwaves->buf_idy)
> + av_freep(showwaves->buf_idy);
> }
>
> static int query_formats(AVFilterContext *ctx)
> @@ -110,14 +115,22 @@ static int query_formats(AVFilterContext *ctx)
>
> static int config_output(AVFilterLink *outlink)
> {
> + int i;
>
Could you put this one down where nb_channels is.
> AVFilterContext *ctx = outlink->src;
> AVFilterLink *inlink = ctx->inputs[0];
> ShowWavesContext *showwaves = ctx->priv;
> + int nb_channels = inlink->channels;
>
> if (!showwaves->n)
> showwaves->n = FFMAX(1, ((double)inlink->sample_rate /
> (showwaves->w * av_q2d(showwaves->rate))) + 0.5);
>
> showwaves->buf_idx = 0;
> + if (!(showwaves->buf_idy = av_malloc_array(nb_channels, 1))) {
>
Use calloc, or av_mallocz_array.
> + av_log(NULL, AV_LOG_ERROR, "Could not allocate showwaves
> buffer\n");
>
This can use ctx : av_log(ctx,..
> + return AVERROR(ENOMEM);
> + }
> + for (i = 0; i <= nb_channels; i++)
> + showwaves->buf_idy[i] = 0;
>
Not needed to manually do this if you use one of above mentioned functions.
> outlink->w = showwaves->w;
> outlink->h = showwaves->h;
> outlink->sample_aspect_ratio = (AVRational){1,1};
> @@ -132,13 +145,18 @@ static int config_output(AVFilterLink *outlink)
>
> inline static int push_frame(AVFilterLink *outlink)
> {
> + AVFilterContext *ctx = outlink->src;
> + AVFilterLink *inlink = ctx->inputs[0];
> ShowWavesContext *showwaves = outlink->src->priv;
> - int ret;
> + int nb_channels = inlink->channels;
> + int ret, i;
>
> if ((ret = ff_filter_frame(outlink, showwaves->outpicref)) >= 0)
> showwaves->req_fullfilled = 1;
> showwaves->outpicref = NULL;
> showwaves->buf_idx = 0;
> + for (i = 0; i <= nb_channels; i++)
> + showwaves->buf_idy[i] = 0;
> return ret;
> }
>
> @@ -207,7 +225,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame
> *insamples)
> *(outpicref->data[0] + showwaves->buf_idx + k *
> linesize) += x;
> 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);
>
FFSWAP.. should be on its own line
+ 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++;
> --
> 1.7.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
More information about the ffmpeg-devel
mailing list