From patchwork Mon Feb 24 12:37:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 17909 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id AC2A744A135 for ; Mon, 24 Feb 2020 14:39:33 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9698668B547; Mon, 24 Feb 2020 14:39:33 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail.red.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8538468B4EE for ; Mon, 24 Feb 2020 14:39:23 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 35D472951AB for ; Mon, 24 Feb 2020 13:39:23 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id 4XkHBOVt0ORi for ; Mon, 24 Feb 2020 13:39:22 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id BADBF2951A8 for ; Mon, 24 Feb 2020 13:39:22 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 8B1E32522B for ; Mon, 24 Feb 2020 13:39:22 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id brSQ5FWRYSGV for ; Mon, 24 Feb 2020 13:39:20 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 725D82522F for ; Mon, 24 Feb 2020 13:39:14 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 3953A20E0357; Mon, 24 Feb 2020 13:39:11 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Mon, 24 Feb 2020 13:37:32 +0100 Message-Id: <20200224123739.31154-6-anton@khirnov.net> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200224123739.31154-1-anton@khirnov.net> References: <20200224123739.31154-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 05/12] vf_fspp: drop the option to use frame-attached QP tables X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This API has been deprecated for five years. --- doc/filters.texi | 6 -- libavfilter/vf_fspp.c | 129 ++++++++++-------------------------------- libavfilter/vf_fspp.h | 3 - 3 files changed, 30 insertions(+), 108 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 43e52f930a..59571a7022 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -11382,18 +11382,12 @@ an integer in the range 4-5. Default value is @code{4}. @item qp Force a constant quantization parameter. It accepts an integer in range 0-63. -If not set, the filter will use the QP from the video stream (if available). @item strength Set filter strength. It accepts an integer in range -15 to 32. Lower values mean more details but also more artifacts, while higher values make the image smoother but also blurrier. Default value is @code{0} − PSNR optimal. -@item use_bframe_qp -Enable the use of the QP from the B-Frames if set to @code{1}. Using this -option may cause flicker since the B-Frames have often larger QP. Default is -@code{0} (not enabled). - @end table @section gblur diff --git a/libavfilter/vf_fspp.c b/libavfilter/vf_fspp.c index c6989046c4..b53ae337c9 100644 --- a/libavfilter/vf_fspp.c +++ b/libavfilter/vf_fspp.c @@ -48,7 +48,6 @@ static const AVOption fspp_options[] = { { "quality", "set quality", OFFSET(log2_count), AV_OPT_TYPE_INT, {.i64 = 4}, 4, MAX_LEVEL, FLAGS }, { "qp", "force a constant quantizer parameter", OFFSET(qp), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 64, FLAGS }, { "strength", "set filter strength", OFFSET(strength), AV_OPT_TYPE_INT, {.i64 = 0}, -15, 32, FLAGS }, - { "use_bframe_qp", "use B-frames' QP", OFFSET(use_bframe_qp), AV_OPT_TYPE_BOOL,{.i64 = 0}, 0, 1, FLAGS }, { NULL } }; @@ -148,15 +147,12 @@ static void mul_thrmat_c(int16_t *thr_adr_noq, int16_t *thr_adr, int q) static void filter(FSPPContext *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, - int width, int height, - uint8_t *qp_store, int qp_stride, int is_luma) + int width, int height, int is_luma) { - int x, x0, y, es, qy, t; + int x, x0, y, es; const int stride = is_luma ? p->temp_stride : (width + 16); const int step = 6 - p->log2_count; - const int qpsh = 4 - p->hsub * !is_luma; - const int qpsv = 4 - p->vsub * !is_luma; DECLARE_ALIGNED(32, int32_t, block_align)[4 * 8 * BLOCKSZ + 4 * 8 * BLOCKSZ]; int16_t *block = (int16_t *)block_align; @@ -186,31 +182,14 @@ static void filter(FSPPContext *p, uint8_t *dst, uint8_t *src, for (y = step; y < height + 8; y += step) { //step= 1,2 const int y1 = y - 8 + step; //l5-7 l4-6; - qy = y - 4; - if (qy > height - 1) qy = height - 1; - if (qy < 0) qy = 0; - - qy = (qy >> qpsv) * qp_stride; p->row_fdct(block, p->src + y * stride + 2 - (y&1), stride, 2); for (x0 = 0; x0 < width + 8 - 8 * (BLOCKSZ - 1); x0 += 8 * (BLOCKSZ - 1)) { p->row_fdct(block + 8 * 8, p->src + y * stride + 8 + x0 + 2 - (y&1), stride, 2 * (BLOCKSZ - 1)); - if (p->qp) - p->column_fidct((int16_t *)(&p->threshold_mtx[0]), block + 0 * 8, block3 + 0 * 8, 8 * (BLOCKSZ - 1)); //yes, this is a HOTSPOT - else - for (x = 0; x < 8 * (BLOCKSZ - 1); x += 8) { - t = x + x0 - 2; //correct t=x+x0-2-(y&1), but its the same - - if (t < 0) t = 0; //t always < width-2 - - t = qp_store[qy + (t >> qpsh)]; - t = ff_norm_qscale(t, p->qscale_type); + p->column_fidct((int16_t *)(&p->threshold_mtx[0]), block + 0 * 8, block3 + 0 * 8, 8 * (BLOCKSZ - 1)); //yes, this is a HOTSPOT - if (t != p->prev_q) p->prev_q = t, p->mul_thrmat((int16_t *)(&p->threshold_mtx_noq[0]), (int16_t *)(&p->threshold_mtx[0]), t); - p->column_fidct((int16_t *)(&p->threshold_mtx[0]), block + x * 8, block3 + x * 8, 8); //yes, this is a HOTSPOT - } p->row_idct(block3 + 0 * 8, p->temp + (y & 15) * stride + x0 + 2 - (y & 1), stride, 2 * (BLOCKSZ - 1)); memmove(block, block + (BLOCKSZ - 1) * 64, 8 * 8 * sizeof(int16_t)); //cycling memmove(block3, block3 + (BLOCKSZ - 1) * 64, 6 * 8 * sizeof(int16_t)); @@ -525,13 +504,6 @@ static int config_input(AVFilterLink *inlink) if (!fspp->temp || !fspp->src) return AVERROR(ENOMEM); - if (!fspp->use_bframe_qp && !fspp->qp) { - fspp->non_b_qp_alloc_size = AV_CEIL_RSHIFT(inlink->w, 4) * AV_CEIL_RSHIFT(inlink->h, 4); - fspp->non_b_qp_table = av_calloc(fspp->non_b_qp_alloc_size, sizeof(*fspp->non_b_qp_table)); - if (!fspp->non_b_qp_table) - return AVERROR(ENOMEM); - } - fspp->store_slice = store_slice_c; fspp->store_slice2 = store_slice2_c; fspp->mul_thrmat = mul_thrmat_c; @@ -552,8 +524,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFilterLink *outlink = ctx->outputs[0]; AVFrame *out = in; - int qp_stride = 0; - uint8_t *qp_table = NULL; int i, bias; int custom_threshold_m[64]; @@ -574,75 +544,37 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) |(((uint64_t)custom_threshold_m[i * 8 + 7]) << 48); } - if (fspp->qp) - fspp->prev_q = fspp->qp, fspp->mul_thrmat((int16_t *)(&fspp->threshold_mtx_noq[0]), (int16_t *)(&fspp->threshold_mtx[0]), fspp->qp); - - /* if we are not in a constant user quantizer mode and we don't want to use - * the quantizers from the B-frames (B-frames often have a higher QP), we - * need to save the qp table from the last non B-frame; this is what the - * following code block does */ - if (!fspp->qp) { - qp_table = av_frame_get_qp_table(in, &qp_stride, &fspp->qscale_type); - - if (qp_table && !fspp->use_bframe_qp && in->pict_type != AV_PICTURE_TYPE_B) { - int w, h; - - /* if the qp stride is not set, it means the QP are only defined on - * a line basis */ - if (!qp_stride) { - w = AV_CEIL_RSHIFT(inlink->w, 4); - h = 1; - } else { - w = qp_stride; - h = AV_CEIL_RSHIFT(inlink->h, 4); - } - if (w * h > fspp->non_b_qp_alloc_size) { - int ret = av_reallocp_array(&fspp->non_b_qp_table, w, h); - if (ret < 0) { - fspp->non_b_qp_alloc_size = 0; - return ret; - } - fspp->non_b_qp_alloc_size = w * h; - } - - av_assert0(w * h <= fspp->non_b_qp_alloc_size); - memcpy(fspp->non_b_qp_table, qp_table, w * h); - } - } + fspp->prev_q = fspp->qp; + fspp->mul_thrmat((int16_t *)(&fspp->threshold_mtx_noq[0]), (int16_t *)(&fspp->threshold_mtx[0]), fspp->qp); if (fspp->log2_count && !ctx->is_disabled) { - if (!fspp->use_bframe_qp && fspp->non_b_qp_table) - qp_table = fspp->non_b_qp_table; - - if (qp_table || fspp->qp) { - const int cw = AV_CEIL_RSHIFT(inlink->w, fspp->hsub); - const int ch = AV_CEIL_RSHIFT(inlink->h, fspp->vsub); - - /* get a new frame if in-place is not possible or if the dimensions - * are not multiple of 8 */ - if (!av_frame_is_writable(in) || (inlink->w & 7) || (inlink->h & 7)) { - const int aligned_w = FFALIGN(inlink->w, 8); - const int aligned_h = FFALIGN(inlink->h, 8); - - out = ff_get_video_buffer(outlink, aligned_w, aligned_h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - out->width = in->width; - out->height = in->height; + const int cw = AV_CEIL_RSHIFT(inlink->w, fspp->hsub); + const int ch = AV_CEIL_RSHIFT(inlink->h, fspp->vsub); + + /* get a new frame if in-place is not possible or if the dimensions + * are not multiple of 8 */ + if (!av_frame_is_writable(in) || (inlink->w & 7) || (inlink->h & 7)) { + const int aligned_w = FFALIGN(inlink->w, 8); + const int aligned_h = FFALIGN(inlink->h, 8); + + out = ff_get_video_buffer(outlink, aligned_w, aligned_h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); } - - filter(fspp, out->data[0], in->data[0], out->linesize[0], in->linesize[0], - inlink->w, inlink->h, qp_table, qp_stride, 1); - filter(fspp, out->data[1], in->data[1], out->linesize[1], in->linesize[1], - cw, ch, qp_table, qp_stride, 0); - filter(fspp, out->data[2], in->data[2], out->linesize[2], in->linesize[2], - cw, ch, qp_table, qp_stride, 0); - emms_c(); + av_frame_copy_props(out, in); + out->width = in->width; + out->height = in->height; } - } + + filter(fspp, out->data[0], in->data[0], out->linesize[0], in->linesize[0], + inlink->w, inlink->h, 1); + filter(fspp, out->data[1], in->data[1], out->linesize[1], in->linesize[1], + cw, ch, 0); + filter(fspp, out->data[2], in->data[2], out->linesize[2], in->linesize[2], + cw, ch, 0); + emms_c(); +} if (in != out) { if (in->data[3]) @@ -659,7 +591,6 @@ static av_cold void uninit(AVFilterContext *ctx) FSPPContext *fspp = ctx->priv; av_freep(&fspp->temp); av_freep(&fspp->src); - av_freep(&fspp->non_b_qp_table); } static const AVFilterPad fspp_inputs[] = { diff --git a/libavfilter/vf_fspp.h b/libavfilter/vf_fspp.h index 73d8c7c771..c2595d1a6b 100644 --- a/libavfilter/vf_fspp.h +++ b/libavfilter/vf_fspp.h @@ -65,9 +65,6 @@ typedef struct FSPPContext { int prev_q; uint8_t *src; int16_t *temp; - uint8_t *non_b_qp_table; - int non_b_qp_alloc_size; - int use_bframe_qp; void (*store_slice)(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride, ptrdiff_t src_stride,