From 893d4068adb9d3d2c118186bdc5645056f0ef172 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz <mfc...@gmail.com> 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 == AVERROR_EOF && s->outpicref[0]) filter_frame(inlink, NULL); return ret; } -- 1.8.3.1
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel