Re: [FFmpeg-devel] [PATCH] avfilter/avf_showcqt: fix frame management

2015-10-13 Thread Muhammad Faiz
On Tue, Oct 13, 2015 at 1:31 PM, Clément Bœsch  wrote:
>
> Did you test if you get the same results with and without the perms
> filter?
>

it gives mostly same result (e.g in common usage with ffplay)
it gives more correct result when  you still need frame reference like this
code

// buffersink is connected to showcqt filter
int i
AVFrame *frame[32];
for (i = 0; i < 32; i++) {
frame[i] = av_frame_alloc();
av_buffersink_get_frame_flags(buffersink, frame[i], 0);
}

the old code will gives incorrect result (frame[0] to frame[30] will be
clobbered by frame[31] because they reference to the same buffers

thanks
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] avfilter/avf_showcqt: fix frame management

2015-10-12 Thread Clément Bœsch
On Tue, Oct 13, 2015 at 12:18:58PM +0700, Muhammad Faiz wrote:
> 

> From 893d4068adb9d3d2c118186bdc5645056f0ef172 Mon Sep 17 00:00:00 2001
> From: Muhammad Faiz 
> Date: Tue, 13 Oct 2015 12:06:37 +0700
> Subject: [PATCH] avfilter/avf_showcqt: fix frame management
> 
> follow frame writability rule
> reuse buffer
> ---
>  libavfilter/avf_showcqt.c | 61 
> +++

Did you test if you get the same results with and without the perms
filter?

[...]

-- 
Clément B.


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


[FFmpeg-devel] [PATCH] avfilter/avf_showcqt: fix frame management

2015-10-12 Thread Muhammad Faiz

From 893d4068adb9d3d2c118186bdc5645056f0ef172 Mon Sep 17 00:00:00 2001
From: Muhammad Faiz 
Date: Tue, 13 Oct 2015 12:06:37 +0700
Subject: [PATCH] avfilter/avf_showcqt: fix frame management

follow frame writability rule
reuse buffer
---
 libavfilter/avf_showcqt.c | 61 +++
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/libavfilter/avf_showcqt.c b/libavfilter/avf_showcqt.c
index e939d8f..5d5fa6c 100644
--- a/libavfilter/avf_showcqt.c
+++ b/libavfilter/avf_showcqt.c
@@ -60,9 +60,12 @@ typedef struct {
 int start, len;
 } Coeffs;
 
+#define NB_OUTPICREF_MAX 16
+
 typedef struct {
 const AVClass *class;
-AVFrame *outpicref;
+AVFrame *outpicref[NB_OUTPICREF_MAX];
+int nb_outpicref;
 FFTContext *fft_context;
 FFTComplex *fft_data;
 FFTComplex *fft_result;
@@ -123,7 +126,8 @@ static av_cold void uninit(AVFilterContext *ctx)
 av_freep(&s->fft_result);
 av_freep(&s->spectogram);
 av_freep(&s->font_alpha);
-av_frame_free(&s->outpicref);
+for (k = 0; k < s->nb_outpicref; k++)
+av_frame_free(&s->outpicref[k]);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -428,11 +432,12 @@ static int config_output(AVFilterLink *outlink)
 s->remaining_fill = fft_len >> 1;
 memset(s->fft_data, 0, fft_len * sizeof(*s->fft_data));
 
-s->outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h);
-if (!s->outpicref)
+s->outpicref[0] = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+if (!s->outpicref[0])
 return AVERROR(ENOMEM);
+s->nb_outpicref = 1;
 
-s->spectogram = av_calloc(spectogram_height, s->outpicref->linesize[0]);
+s->spectogram = av_calloc(spectogram_height, s->outpicref[0]->linesize[0]);
 if (!s->spectogram)
 return AVERROR(ENOMEM);
 
@@ -456,7 +461,7 @@ static int plot_cqt(AVFilterLink *inlink)
 int fft_len = 1 << s->fft_bits;
 FFTSample result[VIDEO_WIDTH][4];
 int x, y, ret = 0;
-int linesize = s->outpicref->linesize[0];
+int linesize = s->outpicref[0]->linesize[0];
 int video_scale = s->fullhd ? 2 : 1;
 int video_width = (VIDEO_WIDTH/2) * video_scale;
 int spectogram_height = (SPECTOGRAM_HEIGHT/2) * video_scale;
@@ -549,10 +554,46 @@ static int plot_cqt(AVFilterLink *inlink)
 
 /* drawing */
 if (!s->spectogram_count) {
-uint8_t *data = (uint8_t*) s->outpicref->data[0];
+AVFrame *outpic = NULL;
+uint8_t *data;
 float rcp_result[VIDEO_WIDTH];
 int total_length = linesize * spectogram_height;
 int back_length = linesize * s->spectogram_index;
+int pic_idx;
+
+/* reuse buffer if it is available */
+/* faster, but not writable to next filters */
+/* become slower if next filters need writable frame */
+for (pic_idx = 0; pic_idx < s->nb_outpicref; pic_idx++) {
+if (av_frame_is_writable(s->outpicref[pic_idx])) {
+outpic = av_frame_clone(s->outpicref[pic_idx]);
+break;
+}
+}
+
+/* allocate buffer and make it reusable if it is possible */
+if (pic_idx == s->nb_outpicref) {
+if (s->nb_outpicref < NB_OUTPICREF_MAX) {
+s->nb_outpicref++;
+av_log(ctx, AV_LOG_DEBUG, "allocating reusable buffer 
(nb_outpicref = %d) "
+   "at frame %"PRId64"\n", s->nb_outpicref, 
s->frame_count);
+s->outpicref[pic_idx] = ff_get_video_buffer(outlink, 
outlink->w, outlink->h);
+if (!s->outpicref[pic_idx])
+return AVERROR(ENOMEM);
+outpic = av_frame_clone(s->outpicref[pic_idx]);
+} else {
+av_log(ctx, AV_LOG_DEBUG, "allocating buffer at frame 
%"PRId64"\n",
+   s->frame_count);
+outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+}
+}
+
+if (!outpic)
+return AVERROR(ENOMEM);
+data = outpic->data[0];
+/* linesize should be consistent accross different call to 
ff_get_video_buffer */
+/* needed for drawing sonogram */
+av_assert0(outpic->linesize[0] == linesize);
 
 for (x = 0; x < video_width; x++)
 rcp_result[x] = 1.0f / (result[x][3]+0.0001f);
@@ -645,8 +686,8 @@ static int plot_cqt(AVFilterLink *inlink)
 if (back_length)
 memcpy(data, s->spectogram, back_length);
 
-s->outpicref->pts = s->frame_count;
-ret = ff_filter_frame(outlink, av_frame_clone(s->outpicref));
+outpic->pts = s->frame_count;
+ret = ff_filter_frame(outlink, outpic);
 s->frame_count++;
 }
 s->spectogram_count = (s->spectogram_count + 1) % s->count;
@@ -721,7 +762,7 @@ static int request_frame(AVFilterLink *outlink)
 int ret;
 
 ret = ff_request_frame(inlink);
-if (ret == AVERROR_EOF && s->outpicref)
+if (ret =