On Thu, Jul 31, 2014 at 2:50 PM, mrskman <mrsk...@gmail.com> wrote: > A few months ago I sent this patch and got some comments, which helped me > to understand how this filter works. Thank you for that and I'm sorry it > took me so long to reply. Here is a better version (atleast for me). > > Problem with the current mode=point is, you can get almost invisible wave > when you set higher resolution output or when there are high amplitudes > in audio stream. > > With this new mode additional points are drawn to make a line between > points and output is readable regardless of the resolution or amplitudes. > > Please review and comment. > > --- > doc/filters.texi | 3 +++ > libavfilter/avf_showwaves.c | 38 +++++++++++++++++++++++++++++++++----- > 2 files changed, 36 insertions(+), 5 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. > + > +@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..48e61d1 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,8 @@ typedef struct { > int w, h; > AVRational rate; > int buf_idx; > + int *buf_idy; /* y coordinate of previous sample for each channel > */ > + int nb_channels; >
This change is not needed. > AVFrame *outpicref; > int req_fullfilled; > int n; > @@ -59,6 +62,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 +76,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,6 +116,7 @@ static int query_formats(AVFilterContext *ctx) > > static int config_output(AVFilterLink *outlink) > { > + int i; > AVFilterContext *ctx = outlink->src; > AVFilterLink *inlink = ctx->inputs[0]; > ShowWavesContext *showwaves = ctx->priv; > @@ -117,7 +124,14 @@ static int config_output(AVFilterLink *outlink) > if (!showwaves->n) > showwaves->n = FFMAX(1, ((double)inlink->sample_rate / > (showwaves->w * av_q2d(showwaves->rate))) + 0.5); > > + showwaves->nb_channels = inlink->channels; > showwaves->buf_idx = 0; > + if (!(showwaves->buf_idy = av_malloc_array(showwaves->nb_channels, > 1))) { > + av_log(NULL, AV_LOG_ERROR, "Could not allocate showwaves > buffer\n"); > + return AVERROR(ENOMEM); > + } > + for (i = 0; i <= showwaves->nb_channels; i++) > + showwaves->buf_idy[i] = 0; > outlink->w = showwaves->w; > outlink->h = showwaves->h; > outlink->sample_aspect_ratio = (AVRational){1,1}; > @@ -133,12 +147,14 @@ static int config_output(AVFilterLink *outlink) > inline static int push_frame(AVFilterLink *outlink) > { > ShowWavesContext *showwaves = outlink->src->priv; > - int ret; > + 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 <= showwaves->nb_channels; i++) > + showwaves->buf_idy[i] = 0; > return ret; > } > > @@ -169,10 +185,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame > *insamples) > AVFrame *outpicref = showwaves->outpicref; > int linesize = outpicref ? outpicref->linesize[0] : 0; > int16_t *p = (int16_t *)insamples->data[0]; > - int nb_channels = inlink->channels; > int i, j, k, h, ret = 0; > const int n = showwaves->n; > - const int x = 255 / (nb_channels * n); /* multiplication factor, > pre-computed to avoid in-loop divisions */ > + const int x = 255 / (showwaves->nb_channels * n); /* multiplication > factor, pre-computed to avoid in-loop divisions */ > > /* draw data in the buffer */ > for (i = 0; i < nb_samples; i++) { > @@ -184,14 +199,14 @@ static int filter_frame(AVFilterLink *inlink, > AVFrame *insamples) > outpicref->width = outlink->w; > outpicref->height = outlink->h; > outpicref->pts = insamples->pts + > - av_rescale_q((p - (int16_t > *)insamples->data[0]) / nb_channels, > + av_rescale_q((p - (int16_t > *)insamples->data[0]) / showwaves->nb_channels, > (AVRational){ 1, > inlink->sample_rate }, > outlink->time_base); > linesize = outpicref->linesize[0]; > for (j = 0; j < outlink->h; j++) > memset(outpicref->data[0] + j * linesize, 0, outlink->w); > } > - for (j = 0; j < nb_channels; j++) { > + for (j = 0; j < showwaves->nb_channels; j++) { > h = showwaves->h/2 - av_rescale(*p++, showwaves->h/2, > MAX_INT16); > switch (showwaves->mode) { > case MODE_POINT: > @@ -207,7 +222,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); > + 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@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel