Re: [FFmpeg-devel] [PATCH v2] avfilter/avf_showcqt: improve pts handling

2016-02-17 Thread Muhammad Faiz
On Wed, Feb 17, 2016 at 9:55 PM, Michael Niedermayer
 wrote:
>
> PS: Muhammad, if you want git write access to maintain this filter,
> just say so.
>
OK, I have sent a mail to you.
Thank's
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH v2] avfilter/avf_showcqt: improve pts handling

2016-02-17 Thread Muhammad Faiz
On Wed, Feb 17, 2016 at 6:26 PM, wm4  wrote:
> On Wed, 17 Feb 2016 10:39:30 +0100
> Paul B Mahol  wrote:
>
>> On 2/16/16, Muhammad Faiz  wrote:
>> > correct output pts based on input pts
>> > make seeking possible
>> > output frame one by one on eof
>> > tested with showinfo filter
>> >
>> > patch attached
>> >
>> > thank's
>> >
>>
>> Tested with mpv, works, so LGTM.
>
> I don't think that's sufficient. Also, the patch author said something
> about seeking - I'm not sure what that means (since libavfilter doesn't
> support seeking, not even flushing), and mpv in particular just
> destroys and recreates the entire graph on seeking out of necessity.

I just post a patch for movie/amovie seek support, and test it for
showcqt filter
ffplay -f lavfi "amovie=$HOME/Music/audio.mp3, asendcmd=c='10 amovie
seek -1|12000|0', asplit[out1],showcqt[out0]"
and it works.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH v2] avfilter/avf_showcqt: improve pts handling

2016-02-17 Thread Michael Niedermayer
On Wed, Feb 17, 2016 at 12:33:49PM +0100, Paul B Mahol wrote:
> On 2/17/16, wm4  wrote:
> > On Wed, 17 Feb 2016 10:39:30 +0100
> > Paul B Mahol  wrote:
> >
> >> On 2/16/16, Muhammad Faiz  wrote:
> >> > correct output pts based on input pts
> >> > make seeking possible
> >> > output frame one by one on eof
> >> > tested with showinfo filter
> >> >
> >> > patch attached
> >> >
> >> > thank's
> >> >
> >>
> >> Tested with mpv, works, so LGTM.
> >
> > I don't think that's sufficient. Also, the patch author said something
> > about seeking - I'm not sure what that means (since libavfilter doesn't
> > support seeking, not even flushing), and mpv in particular just
> > destroys and recreates the entire graph on seeking out of necessity.
> 
> It means what I said, patch LGTM.

applied

thanks

PS: Muhammad, if you want git write access to maintain this filter,
just say so.

[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

In a rich man's house there is no place to spit but his face.
-- Diogenes of Sinope


signature.asc
Description: Digital signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH v2] avfilter/avf_showcqt: improve pts handling

2016-02-17 Thread wm4
On Wed, 17 Feb 2016 12:33:49 +0100
Paul B Mahol  wrote:

> On 2/17/16, wm4  wrote:
> > On Wed, 17 Feb 2016 10:39:30 +0100
> > Paul B Mahol  wrote:
> >  
> >> On 2/16/16, Muhammad Faiz  wrote:  
> >> > correct output pts based on input pts
> >> > make seeking possible
> >> > output frame one by one on eof
> >> > tested with showinfo filter
> >> >
> >> > patch attached
> >> >
> >> > thank's
> >> >  
> >>
> >> Tested with mpv, works, so LGTM.  
> >
> > I don't think that's sufficient. Also, the patch author said something
> > about seeking - I'm not sure what that means (since libavfilter doesn't
> > support seeking, not even flushing), and mpv in particular just
> > destroys and recreates the entire graph on seeking out of necessity.  
> 
> It means what I said, patch LGTM.
> 
> It doesnt anymore creates frame pts out of nothing but takes into account
> input frame pts. When mpv seeks with complex filter graph it recreates
> filtergraph but it doesn't resets pts to start from 0, and why would it.

Ah, I thought that specific issue was already fixed, but it was with
another filter.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH v2] avfilter/avf_showcqt: improve pts handling

2016-02-17 Thread Paul B Mahol
On 2/17/16, wm4  wrote:
> On Wed, 17 Feb 2016 10:39:30 +0100
> Paul B Mahol  wrote:
>
>> On 2/16/16, Muhammad Faiz  wrote:
>> > correct output pts based on input pts
>> > make seeking possible
>> > output frame one by one on eof
>> > tested with showinfo filter
>> >
>> > patch attached
>> >
>> > thank's
>> >
>>
>> Tested with mpv, works, so LGTM.
>
> I don't think that's sufficient. Also, the patch author said something
> about seeking - I'm not sure what that means (since libavfilter doesn't
> support seeking, not even flushing), and mpv in particular just
> destroys and recreates the entire graph on seeking out of necessity.

It means what I said, patch LGTM.

It doesnt anymore creates frame pts out of nothing but takes into account
input frame pts. When mpv seeks with complex filter graph it recreates
filtergraph but it doesn't resets pts to start from 0, and why would it.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH v2] avfilter/avf_showcqt: improve pts handling

2016-02-17 Thread wm4
On Wed, 17 Feb 2016 10:39:30 +0100
Paul B Mahol  wrote:

> On 2/16/16, Muhammad Faiz  wrote:
> > correct output pts based on input pts
> > make seeking possible
> > output frame one by one on eof
> > tested with showinfo filter
> >
> > patch attached
> >
> > thank's
> >  
> 
> Tested with mpv, works, so LGTM.

I don't think that's sufficient. Also, the patch author said something
about seeking - I'm not sure what that means (since libavfilter doesn't
support seeking, not even flushing), and mpv in particular just
destroys and recreates the entire graph on seeking out of necessity.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH v2] avfilter/avf_showcqt: improve pts handling

2016-02-17 Thread wm4
On Wed, 17 Feb 2016 01:13:54 +0700
Muhammad Faiz  wrote:

> On Tue, Feb 16, 2016 at 6:22 PM, wm4  wrote:
> > On Tue, 16 Feb 2016 18:01:16 +0700
> > Muhammad Faiz  wrote:
> ...
> >>  remaining -= s->remaining_fill;
> >> +if (out) {
> >> +int64_t pts = av_rescale_q(insamples->pts, 
> >> inlink->time_base, av_make_q(1, inlink->sample_rate));
> >> +pts += insamples->nb_samples - remaining - s->fft_len/2;
> >> +pts = av_rescale_q(pts, av_make_q(1, 
> >> inlink->sample_rate), outlink->time_base);
> >> +if (FFABS(pts - out->pts) > PTS_TOLERANCE) {
> >> +av_log(ctx, AV_LOG_DEBUG, "changing pts from 
> >> %"PRId64" (%.3f) to %"PRId64" (%.3f).\n",
> >> +   out->pts, out->pts * 
> >> av_q2d(outlink->time_base),
> >> +   pts, pts * av_q2d(outlink->time_base));
> >> +out->pts = pts;
> >> +s->next_pts = pts + PTS_STEP;  
> >
> > What is this code needed for? The PTS_TOLERANCE thing specifically.  
> 
> Because input time_base and output time_base does not match,
> there is probability that linear input pts gives non linear output pts,
> probably differ by 1, e.g 0 11 20 31 40 ... and I prefer linear output pts.
> You may try it with PTS_TOLERANCE set to 0.
> 

Hm ok, that still seems a bit sketchy (a filter shouldn't try to "fix"
timestamps), but probably ok.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH v2] avfilter/avf_showcqt: improve pts handling

2016-02-17 Thread Paul B Mahol
On 2/16/16, Muhammad Faiz  wrote:
> correct output pts based on input pts
> make seeking possible
> output frame one by one on eof
> tested with showinfo filter
>
> patch attached
>
> thank's
>

Tested with mpv, works, so LGTM.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH v2] avfilter/avf_showcqt: improve pts handling

2016-02-16 Thread Muhammad Faiz
On Tue, Feb 16, 2016 at 6:22 PM, wm4  wrote:
> On Tue, 16 Feb 2016 18:01:16 +0700
> Muhammad Faiz  wrote:
>
>> From bc59d4a7636e2f199b3dbda06e8e3bc53e260cae Mon Sep 17 00:00:00 2001
>> From: Muhammad Faiz 
>> Date: Tue, 16 Feb 2016 07:03:37 +0700
>> Subject: [PATCH v2] avfilter/avf_showcqt: improve pts handling
>>
>> correct output pts based on input pts
>> make seeking possible
>> output frame one by one on eof
>> tested with showinfo filter
>>
>> Suggested-by: Paul B Mahol 
>> ---
>>  libavfilter/avf_showcqt.c | 47 
>> +++
>>  libavfilter/avf_showcqt.h |  2 +-
>>  2 files changed, 36 insertions(+), 13 deletions(-)
>>
>> diff --git a/libavfilter/avf_showcqt.c b/libavfilter/avf_showcqt.c
>> index 712a999..6bb2d18 100644
>> --- a/libavfilter/avf_showcqt.c
>> +++ b/libavfilter/avf_showcqt.c
>> @@ -48,6 +48,8 @@
>>  #define FONTCOLOR   "st(0, (midi(f)-59.5)/12);" \
>>  "st(1, if(between(ld(0),0,1), 0.5-0.5*cos(2*PI*ld(0)), 0));" \
>>  "r(1-ld(1)) + b(ld(1))"
>> +#define PTS_STEP 10
>> +#define PTS_TOLERANCE 1
>>
>>  #define OFFSET(x) offsetof(ShowCQTContext, x)
>>  #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
>> @@ -989,11 +991,10 @@ static void process_cqt(ShowCQTContext *s)
>>  yuv_from_cqt(s->c_buf, s->cqt_result, s->sono_g, s->width);
>>  }
>>
>> -static int plot_cqt(AVFilterContext *ctx)
>> +static int plot_cqt(AVFilterContext *ctx, AVFrame **frameout)
>>  {
>>  AVFilterLink *outlink = ctx->outputs[0];
>>  ShowCQTContext *s = ctx->priv;
>> -int ret = 0;
>>
>>  memcpy(s->fft_result, s->fft_data, s->fft_len * sizeof(*s->fft_data));
>>  av_fft_permute(s->fft_ctx, s->fft_result);
>> @@ -1004,7 +1005,7 @@ static int plot_cqt(AVFilterContext *ctx)
>>  if (s->sono_h)
>>  s->update_sono(s->sono_frame, s->c_buf, s->sono_idx);
>>  if (!s->sono_count) {
>> -AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
>> +AVFrame *out = *frameout = ff_get_video_buffer(outlink, outlink->w, 
>> outlink->h);
>>  if (!out)
>>  return AVERROR(ENOMEM);
>>  if (s->bar_h)
>> @@ -1013,14 +1014,13 @@ static int plot_cqt(AVFilterContext *ctx)
>>  s->draw_axis(out, s->axis_frame, s->c_buf, s->bar_h);
>>  if (s->sono_h)
>>  s->draw_sono(out, s->sono_frame, s->bar_h + s->axis_h, 
>> s->sono_idx);
>> -out->pts = s->frame_count;
>> -ret = ff_filter_frame(outlink, out);
>> -s->frame_count++;
>> +out->pts = s->next_pts;
>> +s->next_pts += PTS_STEP;
>>  }
>>  s->sono_count = (s->sono_count + 1) % s->count;
>>  if (s->sono_h)
>>  s->sono_idx = (s->sono_idx + s->sono_h - 1) % s->sono_h;
>> -return ret;
>> +return 0;
>>  }
>>
>>  /* main filter control */
>> @@ -1133,7 +1133,7 @@ static int config_output(AVFilterLink *outlink)
>>  s->format = outlink->format;
>>  outlink->sample_aspect_ratio = av_make_q(1, 1);
>>  outlink->frame_rate = s->rate;
>> -outlink->time_base = av_inv_q(s->rate);
>> +outlink->time_base = av_mul_q(av_inv_q(s->rate), av_make_q(1, 
>> PTS_STEP));
>>  av_log(ctx, AV_LOG_INFO, "video: %dx%d %s %d/%d fps, bar_h = %d, axis_h 
>> = %d, sono_h = %d.\n",
>> s->width, s->height, av_get_pix_fmt_name(s->format), 
>> s->rate.num, s->rate.den,
>> s->bar_h, s->axis_h, s->sono_h);
>> @@ -1209,7 +1209,7 @@ static int config_output(AVFilterLink *outlink)
>>  return AVERROR(ENOMEM);
>>
>>  s->sono_count = 0;
>> -s->frame_count = 0;
>> +s->next_pts = 0;
>>  s->sono_idx = 0;
>>  s->remaining_fill = s->fft_len / 2;
>>  s->remaining_frac = 0;
>> @@ -1232,14 +1232,16 @@ static int config_output(AVFilterLink *outlink)
>>  static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
>>  {
>>  AVFilterContext *ctx = inlink->dst;
>> +AVFilterLink *outlink = ctx->outputs[0];
>>  ShowCQTContext *s = ctx->priv;
>>  int remaining, step, ret, x, i, j, m;
>>  float *audio_data;
>> +AVFrame *out = NULL;
>>
>>  if (!insamples) {
>>  while (s->remaining_fill < s->fft_len / 2) {
>>  memset(>fft_data[s->fft_len - s->remaining_fill], 0, 
>> sizeof(*s->fft_data) * s->remaining_fill);
>> -ret = plot_cqt(ctx);
>> +ret = plot_cqt(ctx, );
>>  if (ret < 0)
>>  return ret;
>>
>> @@ -1248,6 +1250,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame 
>> *insamples)
>>  for (x = 0; x < (s->fft_len-step); x++)
>>  s->fft_data[x] = s->fft_data[x+step];
>>  s->remaining_fill += step;
>> +
>> +if (out)
>> +return ff_filter_frame(outlink, out);
>>  }
>>  return AVERROR_EOF;
>>  }
>> @@ -1263,12 +1268,30 @@ static int filter_frame(AVFilterLink 

Re: [FFmpeg-devel] [PATCH v2] avfilter/avf_showcqt: improve pts handling

2016-02-16 Thread Muhammad Faiz
On Tue, Feb 16, 2016 at 6:22 PM, wm4  wrote:
> On Tue, 16 Feb 2016 18:01:16 +0700
> Muhammad Faiz  wrote:
>
>> From bc59d4a7636e2f199b3dbda06e8e3bc53e260cae Mon Sep 17 00:00:00 2001
>> From: Muhammad Faiz 
>> Date: Tue, 16 Feb 2016 07:03:37 +0700
>> Subject: [PATCH v2] avfilter/avf_showcqt: improve pts handling
>>
>> correct output pts based on input pts
>> make seeking possible
>> output frame one by one on eof
>> tested with showinfo filter
>>
>> Suggested-by: Paul B Mahol 
>> ---
>>  libavfilter/avf_showcqt.c | 47 
>> +++
>>  libavfilter/avf_showcqt.h |  2 +-
>>  2 files changed, 36 insertions(+), 13 deletions(-)
>>
>> diff --git a/libavfilter/avf_showcqt.c b/libavfilter/avf_showcqt.c
>> index 712a999..6bb2d18 100644
>> --- a/libavfilter/avf_showcqt.c
>> +++ b/libavfilter/avf_showcqt.c
>> @@ -48,6 +48,8 @@
>>  #define FONTCOLOR   "st(0, (midi(f)-59.5)/12);" \
>>  "st(1, if(between(ld(0),0,1), 0.5-0.5*cos(2*PI*ld(0)), 0));" \
>>  "r(1-ld(1)) + b(ld(1))"
>> +#define PTS_STEP 10
>> +#define PTS_TOLERANCE 1
>>
>>  #define OFFSET(x) offsetof(ShowCQTContext, x)
>>  #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
>> @@ -989,11 +991,10 @@ static void process_cqt(ShowCQTContext *s)
>>  yuv_from_cqt(s->c_buf, s->cqt_result, s->sono_g, s->width);
>>  }
>>
>> -static int plot_cqt(AVFilterContext *ctx)
>> +static int plot_cqt(AVFilterContext *ctx, AVFrame **frameout)
>>  {
>>  AVFilterLink *outlink = ctx->outputs[0];
>>  ShowCQTContext *s = ctx->priv;
>> -int ret = 0;
>>
>>  memcpy(s->fft_result, s->fft_data, s->fft_len * sizeof(*s->fft_data));
>>  av_fft_permute(s->fft_ctx, s->fft_result);
>> @@ -1004,7 +1005,7 @@ static int plot_cqt(AVFilterContext *ctx)
>>  if (s->sono_h)
>>  s->update_sono(s->sono_frame, s->c_buf, s->sono_idx);
>>  if (!s->sono_count) {
>> -AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
>> +AVFrame *out = *frameout = ff_get_video_buffer(outlink, outlink->w, 
>> outlink->h);
>>  if (!out)
>>  return AVERROR(ENOMEM);
>>  if (s->bar_h)
>> @@ -1013,14 +1014,13 @@ static int plot_cqt(AVFilterContext *ctx)
>>  s->draw_axis(out, s->axis_frame, s->c_buf, s->bar_h);
>>  if (s->sono_h)
>>  s->draw_sono(out, s->sono_frame, s->bar_h + s->axis_h, 
>> s->sono_idx);
>> -out->pts = s->frame_count;
>> -ret = ff_filter_frame(outlink, out);
>> -s->frame_count++;
>> +out->pts = s->next_pts;
>> +s->next_pts += PTS_STEP;
>>  }
>>  s->sono_count = (s->sono_count + 1) % s->count;
>>  if (s->sono_h)
>>  s->sono_idx = (s->sono_idx + s->sono_h - 1) % s->sono_h;
>> -return ret;
>> +return 0;
>>  }
>>
>>  /* main filter control */
>> @@ -1133,7 +1133,7 @@ static int config_output(AVFilterLink *outlink)
>>  s->format = outlink->format;
>>  outlink->sample_aspect_ratio = av_make_q(1, 1);
>>  outlink->frame_rate = s->rate;
>> -outlink->time_base = av_inv_q(s->rate);
>> +outlink->time_base = av_mul_q(av_inv_q(s->rate), av_make_q(1, 
>> PTS_STEP));
>>  av_log(ctx, AV_LOG_INFO, "video: %dx%d %s %d/%d fps, bar_h = %d, axis_h 
>> = %d, sono_h = %d.\n",
>> s->width, s->height, av_get_pix_fmt_name(s->format), 
>> s->rate.num, s->rate.den,
>> s->bar_h, s->axis_h, s->sono_h);
>> @@ -1209,7 +1209,7 @@ static int config_output(AVFilterLink *outlink)
>>  return AVERROR(ENOMEM);
>>
>>  s->sono_count = 0;
>> -s->frame_count = 0;
>> +s->next_pts = 0;
>>  s->sono_idx = 0;
>>  s->remaining_fill = s->fft_len / 2;
>>  s->remaining_frac = 0;
>> @@ -1232,14 +1232,16 @@ static int config_output(AVFilterLink *outlink)
>>  static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
>>  {
>>  AVFilterContext *ctx = inlink->dst;
>> +AVFilterLink *outlink = ctx->outputs[0];
>>  ShowCQTContext *s = ctx->priv;
>>  int remaining, step, ret, x, i, j, m;
>>  float *audio_data;
>> +AVFrame *out = NULL;
>>
>>  if (!insamples) {
>>  while (s->remaining_fill < s->fft_len / 2) {
>>  memset(>fft_data[s->fft_len - s->remaining_fill], 0, 
>> sizeof(*s->fft_data) * s->remaining_fill);
>> -ret = plot_cqt(ctx);
>> +ret = plot_cqt(ctx, );
>>  if (ret < 0)
>>  return ret;
>>
>> @@ -1248,6 +1250,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame 
>> *insamples)
>>  for (x = 0; x < (s->fft_len-step); x++)
>>  s->fft_data[x] = s->fft_data[x+step];
>>  s->remaining_fill += step;
>> +
>> +if (out)
>> +return ff_filter_frame(outlink, out);
>>  }
>>  return AVERROR_EOF;
>>  }
>> @@ -1263,12 +1268,30 @@ static int filter_frame(AVFilterLink 

[FFmpeg-devel] [PATCH v2] avfilter/avf_showcqt: improve pts handling

2016-02-16 Thread Muhammad Faiz
correct output pts based on input pts
make seeking possible
output frame one by one on eof
tested with showinfo filter

patch attached

thank's
From bc59d4a7636e2f199b3dbda06e8e3bc53e260cae Mon Sep 17 00:00:00 2001
From: Muhammad Faiz 
Date: Tue, 16 Feb 2016 07:03:37 +0700
Subject: [PATCH v2] avfilter/avf_showcqt: improve pts handling

correct output pts based on input pts
make seeking possible
output frame one by one on eof
tested with showinfo filter

Suggested-by: Paul B Mahol 
---
 libavfilter/avf_showcqt.c | 47 +++
 libavfilter/avf_showcqt.h |  2 +-
 2 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/libavfilter/avf_showcqt.c b/libavfilter/avf_showcqt.c
index 712a999..6bb2d18 100644
--- a/libavfilter/avf_showcqt.c
+++ b/libavfilter/avf_showcqt.c
@@ -48,6 +48,8 @@
 #define FONTCOLOR   "st(0, (midi(f)-59.5)/12);" \
 "st(1, if(between(ld(0),0,1), 0.5-0.5*cos(2*PI*ld(0)), 0));" \
 "r(1-ld(1)) + b(ld(1))"
+#define PTS_STEP 10
+#define PTS_TOLERANCE 1
 
 #define OFFSET(x) offsetof(ShowCQTContext, x)
 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
@@ -989,11 +991,10 @@ static void process_cqt(ShowCQTContext *s)
 yuv_from_cqt(s->c_buf, s->cqt_result, s->sono_g, s->width);
 }
 
-static int plot_cqt(AVFilterContext *ctx)
+static int plot_cqt(AVFilterContext *ctx, AVFrame **frameout)
 {
 AVFilterLink *outlink = ctx->outputs[0];
 ShowCQTContext *s = ctx->priv;
-int ret = 0;
 
 memcpy(s->fft_result, s->fft_data, s->fft_len * sizeof(*s->fft_data));
 av_fft_permute(s->fft_ctx, s->fft_result);
@@ -1004,7 +1005,7 @@ static int plot_cqt(AVFilterContext *ctx)
 if (s->sono_h)
 s->update_sono(s->sono_frame, s->c_buf, s->sono_idx);
 if (!s->sono_count) {
-AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+AVFrame *out = *frameout = ff_get_video_buffer(outlink, outlink->w, outlink->h);
 if (!out)
 return AVERROR(ENOMEM);
 if (s->bar_h)
@@ -1013,14 +1014,13 @@ static int plot_cqt(AVFilterContext *ctx)
 s->draw_axis(out, s->axis_frame, s->c_buf, s->bar_h);
 if (s->sono_h)
 s->draw_sono(out, s->sono_frame, s->bar_h + s->axis_h, s->sono_idx);
-out->pts = s->frame_count;
-ret = ff_filter_frame(outlink, out);
-s->frame_count++;
+out->pts = s->next_pts;
+s->next_pts += PTS_STEP;
 }
 s->sono_count = (s->sono_count + 1) % s->count;
 if (s->sono_h)
 s->sono_idx = (s->sono_idx + s->sono_h - 1) % s->sono_h;
-return ret;
+return 0;
 }
 
 /* main filter control */
@@ -1133,7 +1133,7 @@ static int config_output(AVFilterLink *outlink)
 s->format = outlink->format;
 outlink->sample_aspect_ratio = av_make_q(1, 1);
 outlink->frame_rate = s->rate;
-outlink->time_base = av_inv_q(s->rate);
+outlink->time_base = av_mul_q(av_inv_q(s->rate), av_make_q(1, PTS_STEP));
 av_log(ctx, AV_LOG_INFO, "video: %dx%d %s %d/%d fps, bar_h = %d, axis_h = %d, sono_h = %d.\n",
s->width, s->height, av_get_pix_fmt_name(s->format), s->rate.num, s->rate.den,
s->bar_h, s->axis_h, s->sono_h);
@@ -1209,7 +1209,7 @@ static int config_output(AVFilterLink *outlink)
 return AVERROR(ENOMEM);
 
 s->sono_count = 0;
-s->frame_count = 0;
+s->next_pts = 0;
 s->sono_idx = 0;
 s->remaining_fill = s->fft_len / 2;
 s->remaining_frac = 0;
@@ -1232,14 +1232,16 @@ static int config_output(AVFilterLink *outlink)
 static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
 {
 AVFilterContext *ctx = inlink->dst;
+AVFilterLink *outlink = ctx->outputs[0];
 ShowCQTContext *s = ctx->priv;
 int remaining, step, ret, x, i, j, m;
 float *audio_data;
+AVFrame *out = NULL;
 
 if (!insamples) {
 while (s->remaining_fill < s->fft_len / 2) {
 memset(>fft_data[s->fft_len - s->remaining_fill], 0, sizeof(*s->fft_data) * s->remaining_fill);
-ret = plot_cqt(ctx);
+ret = plot_cqt(ctx, );
 if (ret < 0)
 return ret;
 
@@ -1248,6 +1250,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
 for (x = 0; x < (s->fft_len-step); x++)
 s->fft_data[x] = s->fft_data[x+step];
 s->remaining_fill += step;
+
+if (out)
+return ff_filter_frame(outlink, out);
 }
 return AVERROR_EOF;
 }
@@ -1263,12 +1268,30 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
 s->fft_data[j+m].re = audio_data[2*(i+m)];
 s->fft_data[j+m].im = audio_data[2*(i+m)+1];
 }
-ret = plot_cqt(ctx);
+ret = plot_cqt(ctx, );
 if (ret < 0) {
 av_frame_free();
 return ret;
 }
 remaining -=