From patchwork Wed Mar 13 00:17:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 12298 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 613EF447D94 for ; Wed, 13 Mar 2019 02:18:05 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4786F68A831; Wed, 13 Mar 2019 02:18:05 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5EB0E68A7B0 for ; Wed, 13 Mar 2019 02:17:57 +0200 (EET) Received: by mail-wm1-f51.google.com with SMTP id y15so108161wma.0 for ; Tue, 12 Mar 2019 17:17:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=tBLO8csW+WPzM4yPXiziK7Nl02mzxLwPwTCEe2VDDjA=; b=r5sAVhEz/UsqHtf8d8/4VSFwYtRSVkFY22XOp3HdpYfcYejF84cucwH9XRCpRbXHWI B+WXEfyrN0qbake/AxY//EQLJ4JvT3KYktZ6CyAdg7xz1vtLHXpXHKlL7574mZU3p0wX FL+yvqT2ZfnjYIbEX9NvIzBrftDHd/ZykApFA34kZzKnCNw5VDqOlIFWmFuSTlc+SM2J yK9QnHbaTC0dpBv//0iAuosNoC+6tjj+ZveGpUQFU5naxv4mvk4g7onKSmASrbc+QNHj M/IYw1XfFuLlkzsi3bGsAaHl2uWLjoBV2ZQLihJbAvt6dYNuKhgSFTSLlWOmGG9GElr5 XQ1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tBLO8csW+WPzM4yPXiziK7Nl02mzxLwPwTCEe2VDDjA=; b=rtgKYXfDoKes+ZlnoiX1e60ysAz495QLTwHtdIc84y00aMwU9l8PVoVKIaSwwRrj4R 6eHm3nC6SpJp8t/4updcWdFGrC/mHJdznn0U8CBmqP2+aEyNN82D1Oj1vc0RH321x+9V 075fAFBQ2NDAx/glJjAR4S4BXQSn7iXJfpqIWO31m6oeQ3nOvwWONjoJnO0MXHuFydMa n/2X09SReJvBBE6luRdxAVDuRAVgoGX3Wtbt+bTn67S5Gi4Okk/c8z1gBAcTPpR/aWpF ZdymzSCp17fgbPfJhX4kw/9TG9TFo/Tnll4/Xh5EeCyVe/ySCOzUQKzsXFUvOJe+jzWa z63g== X-Gm-Message-State: APjAAAW5n541/3TT1fvdSLJFC8YCFk/eEaN6O3tnFsRdXwoh1uUDa9tI 0xLf89qaiXW9dCy5RuIz9TLUYZq11sQ= X-Google-Smtp-Source: APXvYqyYdhy1X0Ed7Su0QPM9HTu7EyC/Mc7eVwJiwo75++cFLLdeqol2RYORKSOasXzlfQlCxgBp6Q== X-Received: by 2002:a1c:6506:: with SMTP id z6mr202279wmb.153.1552436276243; Tue, 12 Mar 2019 17:17:56 -0700 (PDT) Received: from rywe.jkqxz.net (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id u17sm32505710wrg.71.2019.03.12.17.17.55 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 12 Mar 2019 17:17:55 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Wed, 13 Mar 2019 00:17:45 +0000 Message-Id: <20190313001748.11781-3-sw@jkqxz.net> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190313001748.11781-1-sw@jkqxz.net> References: <20190313001748.11781-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 3/6] libx264: Update ROI behaviour to match documentation 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" Fix the quantisation offset - use the whole range, and don't change the offset size based on bit depth. Iterate the list in reverse order. The first region in the list is the one that applies in the case of overlapping regions. --- libavcodec/libx264.c | 51 ++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 87e6fe7c94..f5b9b8b821 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -285,16 +285,18 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int nnal, i, ret; x264_picture_t pic_out = {0}; int pict_type; + int bit_depth; int64_t *out_opaque; AVFrameSideData *sd; x264_picture_init( &x4->pic ); x4->pic.img.i_csp = x4->params.i_csp; #if X264_BUILD >= 153 - if (x4->params.i_bitdepth > 8) + bit_depth = x4->params.i_bitdepth; #else - if (x264_bit_depth > 8) + bit_depth = x264_bit_depth; #endif + if (bit_depth > 8) x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH; x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt); @@ -359,45 +361,48 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, if (frame->interlaced_frame == 0) { int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE; int mby = (frame->height + MB_SIZE - 1) / MB_SIZE; + int qp_range = 51 + 6 * (bit_depth - 8); int nb_rois; - AVRegionOfInterest* roi; - float* qoffsets; + const AVRegionOfInterest *roi; + float *qoffsets; + + roi = (const AVRegionOfInterest*)sd->data; + if (!roi->self_size || sd->size % roi->self_size != 0) { + av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n"); + return AVERROR(EINVAL); + } + nb_rois = sd->size / roi->self_size; + qoffsets = av_mallocz_array(mbx * mby, sizeof(*qoffsets)); if (!qoffsets) return AVERROR(ENOMEM); - nb_rois = sd->size / sizeof(AVRegionOfInterest); - roi = (AVRegionOfInterest*)sd->data; - for (int count = 0; count < nb_rois; count++) { - int starty = av_clip(roi->y / MB_SIZE, 0, mby); - int endy = av_clip((roi->y + roi->height + MB_SIZE - 1) / MB_SIZE, 0, mby); - int startx = av_clip(roi->x / MB_SIZE, 0, mbx); - int endx = av_clip((roi->x + roi->width + MB_SIZE - 1) / MB_SIZE, 0, mbx); + // This list must be iterated in reverse because the first + // region in the list applies when regions overlap. + for (int i = nb_rois - 1; i >= 0; i--) { + int startx, endx, starty, endy; float qoffset; + roi = (const AVRegionOfInterest*)(sd->data + roi->self_size * i); + + starty = av_clip(roi->y / MB_SIZE, 0, mby); + endy = av_clip((roi->y + roi->height + MB_SIZE - 1) / MB_SIZE, 0, mby); + startx = av_clip(roi->x / MB_SIZE, 0, mbx); + endx = av_clip((roi->x + roi->width + MB_SIZE - 1) / MB_SIZE, 0, mbx); + if (roi->qoffset.den == 0) { av_free(qoffsets); - av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den should not be zero.\n"); + av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n"); return AVERROR(EINVAL); } qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den; - qoffset = av_clipf(qoffset, -1.0f, 1.0f); - - // 25 is a number that I think it is a possible proper scale value. - qoffset = qoffset * 25; + qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range); for (int y = starty; y < endy; y++) { for (int x = startx; x < endx; x++) { qoffsets[x + y*mbx] = qoffset; } } - - if (roi->self_size == 0) { - av_free(qoffsets); - av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.self_size should be set to sizeof(AVRegionOfInterest).\n"); - return AVERROR(EINVAL); - } - roi = (AVRegionOfInterest*)((char*)roi + roi->self_size); } x4->pic.prop.quant_offsets = qoffsets;