From patchwork Wed Aug 26 15:58:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21935 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 F3676448EC1 for ; Wed, 26 Aug 2020 19:04:17 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D050B68AC85; Wed, 26 Aug 2020 19:04:17 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f195.google.com (mail-pf1-f195.google.com [209.85.210.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 51A4068AB18 for ; Wed, 26 Aug 2020 19:04:10 +0300 (EEST) Received: by mail-pf1-f195.google.com with SMTP id m71so1220387pfd.1 for ; Wed, 26 Aug 2020 09:04:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=7SsBHLcUbrsGWagCGMAdHQSuTa81mM/Z4XwCjEwekwg=; b=dKnO4K1PUcLuVckwisS9flqEQkDrm+MkkOH63gCU5y29jyCB5Wi2h2TFTAnnDQ3FGk AVrvbOQM48WhMxkapIYf7xrb0PzUBu/Ty4sWZfra24JwJ2yrI5+lRoUXi3oOhFJJoCyL DXYiEO5mgK6THi6Gi5hnJYZOxFxrQzSFwOWCUc12mZvvEtIxgleEjJ/uZXPGLnkmzbcY 3JawpQiEQVOIKulNWzG32ny2FvhzKzqM0JjKXnAuLqI0mTpbnR7z04Q57KF5eMCt4bZp 71CbtSgF9v7C1T7+1IWYgTqRt8kgfBo99UtMQyqzpkCDm0LhzIqGjegD1jGX0Ijj5Tm8 PCOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=7SsBHLcUbrsGWagCGMAdHQSuTa81mM/Z4XwCjEwekwg=; b=E9Qtv2FfDNu4h2dVYIi2dQBXERciOJulq/dcnEP0d0hunyW61+pQfKFqpMdp96b4gY 0ZcJ3D5a+7bfeH3aXb2e7MSQRbtcvMPZp24+0PJHvNtPHJFkcYm/plpyP/P3n0phCvs4 FiT2CCxnYT1iWVdnBkQIrhMDcpKFB4mSpLw21TmKb84gt9kWLb2fObwHZow26cv8zC3+ 75QbPzulvmLCX5XdACvt9RzbIf503PjT3hnu6QtXOB/rs4ln5HhsF8VuW/y8Vak33nVx 0vwCjWbXMCatG1/CO5/nx/8VFVMLBlkRudBVES5hiadWFvW3hrNCyl8NZqu19FaHGwtf nQsg== X-Gm-Message-State: AOAM532+CLEFhji+Iods7QyxqKqAGBCqkB2hkQmMCBhTGMSXSYJ9bflT i9Js3agayx3sd0dPVf/ylgrbzpovI2bBHw== X-Google-Smtp-Source: ABdhPJz7AcuOQx38ZU0Xi++oEv4768ZXU3wMQvcjPH1FrYMsw3XvHrPj99AukyYF/mwYRepyeSnyMw== X-Received: by 2002:a63:c62:: with SMTP id 34mr11300621pgm.115.1598457505414; Wed, 26 Aug 2020 08:58:25 -0700 (PDT) Received: from localhost.localdomain ([122.167.211.143]) by smtp.gmail.com with ESMTPSA id n22sm2505555pjq.25.2020.08.26.08.58.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2020 08:58:24 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Wed, 26 Aug 2020 21:28:15 +0530 Message-Id: <20200826155818.8777-1-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [RFC PATCH v6 1/4] libavcodec/jpeg2000: Make tag tree functions non static 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 Cc: Gautam Ramakrishnan MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Gautam Ramakrishnan This patch makes the tag_tree_zero() and tag_tree_size() functions non static and callable from other files. --- libavcodec/jpeg2000.c | 12 ++++++------ libavcodec/jpeg2000.h | 3 +++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index 1aca31ffa4..26e09fbe38 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -39,7 +39,7 @@ /* tag tree routines */ /* allocate the memory for tag tree */ -static int32_t tag_tree_size(int w, int h) +int32_t ff_tag_tree_size(int w, int h) { int64_t res = 0; while (w > 1 || h > 1) { @@ -57,7 +57,7 @@ static Jpeg2000TgtNode *ff_jpeg2000_tag_tree_init(int w, int h) Jpeg2000TgtNode *res, *t, *t2; int32_t tt_size; - tt_size = tag_tree_size(w, h); + tt_size = ff_tag_tree_size(w, h); t = res = av_mallocz_array(tt_size, sizeof(*t)); if (!res) @@ -82,9 +82,9 @@ static Jpeg2000TgtNode *ff_jpeg2000_tag_tree_init(int w, int h) return res; } -static void tag_tree_zero(Jpeg2000TgtNode *t, int w, int h) +void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h) { - int i, siz = tag_tree_size(w, h); + int i, siz = ff_tag_tree_size(w, h); for (i = 0; i < siz; i++) { t[i].val = 0; @@ -567,8 +567,8 @@ void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty) Jpeg2000Band *band = rlevel->band + bandno; for(precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++) { Jpeg2000Prec *prec = band->prec + precno; - tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height); - tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height); + ff_tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height); + ff_tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height); for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) { Jpeg2000Cblk *cblk = prec->cblk + cblkno; cblk->length = 0; diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index 5b0627c3dc..c3437b02fe 100644 --- a/libavcodec/jpeg2000.h +++ b/libavcodec/jpeg2000.h @@ -290,4 +290,7 @@ static inline int needs_termination(int style, int passno) { return 0; } +int32_t ff_tag_tree_size(int w, int h); +void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h); + #endif /* AVCODEC_JPEG2000_H */ From patchwork Wed Aug 26 15:58:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21932 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 CB76544A7B7 for ; Wed, 26 Aug 2020 18:58:37 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id AB676689722; Wed, 26 Aug 2020 18:58:37 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pj1-f67.google.com (mail-pj1-f67.google.com [209.85.216.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E888D687FAE for ; Wed, 26 Aug 2020 18:58:30 +0300 (EEST) Received: by mail-pj1-f67.google.com with SMTP id z18so1090572pjr.2 for ; Wed, 26 Aug 2020 08:58:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QPypVBVgu1ELphu43nw2aW+B8KoUEPyv8hNfJNOt138=; b=Rjcer3MLtXAO8eDqft0+ooSEDaWrEKzqdPasXQhGFfnUVGMmh8sS1jNTRIT4FmTSex eOMsoRgX54MNep6Jx1Td+FeQcYDgKrNifPiKw2OVFGffIzum6hDlv3pi+3rQNOnzs2ut gYnyNwW74e+6Ck+xDQmW6DsgcwafZbdUGT+1CHi0iuRjYqmQb7pEtY1tsqacBOTUAyR4 02VtrHEWDxNfEOYoTblK8dVB6KPcmdOkCP4f+1QkALoJDJEqu2b7FdTT3IrK1L81amcE DGFzU25eugIeoTsEJwehs2qZNoub4ev+ODJ/XZLbwnsUaiMcB0SwyFBV/T1v80t8lPCO He7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=QPypVBVgu1ELphu43nw2aW+B8KoUEPyv8hNfJNOt138=; b=kuSgFHH10+xe+NjoOCIiDOuu4JxkAy0jA0HJjyF8jxAQqJpsqmQMUVHO30CFGG8ESX V835OE4S/cXmO8vl4pEpFyI4ngbSfegPf6yTom3cKoitfnD13ESJeVzWj/ikWh1I/XWr pnhXXyBLZqGROXndWpKrIEsAifhwENFFjoQSvRpX/RIoLpps49xdJ3C32JmkzrqPDP2m mySNP/lRLx0PQCc6r3VzrXkuXDf0puRmcXRhxW+fTMhn0MSSX3I1hP95VQKl0NMRtWbQ K3hn+7yTdiP2o++iaBdZ3irZSQOwJEwq1xitEYrVxtSMbm3cROQQQGEmJ2qEUEyOxylH NKqQ== X-Gm-Message-State: AOAM530O0l74NJJaJa1KxS+xvLm51wg758voP6+nrOOryfNaJyiNvCRm TIj5UtFsEMbHd3uCoC+d42TNCURcz8jImw== X-Google-Smtp-Source: ABdhPJyFhzrhFuHQJt5mIZcauOySpjTs9bGNqCGrvBlGtgM4lD9Oi4Hx4WlQ0Kaw/S3VvG0r5+7F6w== X-Received: by 2002:a17:90a:644b:: with SMTP id y11mr6886217pjm.13.1598457508535; Wed, 26 Aug 2020 08:58:28 -0700 (PDT) Received: from localhost.localdomain ([122.167.211.143]) by smtp.gmail.com with ESMTPSA id n22sm2505555pjq.25.2020.08.26.08.58.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2020 08:58:28 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Wed, 26 Aug 2020 21:28:16 +0530 Message-Id: <20200826155818.8777-2-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200826155818.8777-1-gautamramk@gmail.com> References: <20200826155818.8777-1-gautamramk@gmail.com> Subject: [FFmpeg-devel] [RFC PATCH v6 2/4] libavcodec/j2kenc: Fix tag tree coding 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 Cc: Gautam Ramakrishnan MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Gautam Ramakrishnan The implementation of tag tree encoding was incorrect. However, this error was not visible as the current j2k encoder encodes only 1 layer. This patch fixes tag tree coding for JPEG2000 such tag tree coding would work for multi layer encoding. --- libavcodec/j2kenc.c | 41 +++++++++++++++++++++++++---------------- libavcodec/jpeg2000.c | 1 + libavcodec/jpeg2000.h | 1 + 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index 16863f8e8c..87acd2d5c9 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -242,27 +242,36 @@ static void j2k_flush(Jpeg2000EncoderContext *s) static void tag_tree_code(Jpeg2000EncoderContext *s, Jpeg2000TgtNode *node, int threshold) { Jpeg2000TgtNode *stack[30]; - int sp = 1, curval = 0; - stack[0] = node; + int sp = -1, curval = 0; - node = node->parent; - while(node){ - if (node->vis){ - curval = node->val; - break; - } - node->vis++; - stack[sp++] = node; + while(node->parent){ + stack[++sp] = node; node = node->parent; } - while(--sp >= 0){ - if (stack[sp]->val >= threshold){ + + while (1) { + if (curval > node->temp_val) + node->temp_val = curval; + else { + curval = node->temp_val; + } + + if (node->val >= threshold) { put_bits(s, 0, threshold - curval); - break; + curval = threshold; + } else { + put_bits(s, 0, node->val - curval); + curval = node->val; + if (!node->vis) { + put_bits(s, 1, 1); + node->vis = 1; + } } - put_bits(s, 0, stack[sp]->val - curval); - put_bits(s, 1, 1); - curval = stack[sp]->val; + + node->temp_val = curval; + if (sp < 0) + break; + node = stack[sp--]; } } diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index 26e09fbe38..3d3e7ec313 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -88,6 +88,7 @@ void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h) for (i = 0; i < siz; i++) { t[i].val = 0; + t[i].temp_val = 0; t[i].vis = 0; } } diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index c3437b02fe..ad58b1ae88 100644 --- a/libavcodec/jpeg2000.h +++ b/libavcodec/jpeg2000.h @@ -127,6 +127,7 @@ typedef struct Jpeg2000T1Context { typedef struct Jpeg2000TgtNode { uint8_t val; + uint8_t temp_val; uint8_t vis; struct Jpeg2000TgtNode *parent; } Jpeg2000TgtNode; From patchwork Wed Aug 26 15:58:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21933 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 CCDCD44A7B7 for ; Wed, 26 Aug 2020 18:58:40 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B3BB868AB04; Wed, 26 Aug 2020 18:58:40 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f196.google.com (mail-pf1-f196.google.com [209.85.210.196]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6E493687FAE for ; Wed, 26 Aug 2020 18:58:34 +0300 (EEST) Received: by mail-pf1-f196.google.com with SMTP id t9so1198218pfq.8 for ; Wed, 26 Aug 2020 08:58:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CoNckbYPyPOw79FI/5hkDMNYgaNFJcBXssk0Rr4bvzQ=; b=mBkjA9MdPvhIElhbdj5RIP8DRa0j4cV5Lq4QyKOmz2kFTA51W0/YNQxMjfAKeMDLK9 XRuJQ1ZyHtA0BhkSrvXlxOCteTKWIwDill0MUU05+PhZH69qFcwGS6K9zj1TAksJR8Wd mJZcRRJODE/IoG2x3RdIK7lR/Yg6kQac+lojzLwPVNKG4dOI31hY7N6TFE3WJEWVQFux bgd5ZyEoKdTgCPB8COCHE6O6KS3fmPRfYMpnlfpfbrneHMh4uexoUZ5D1G2xUtiHGZjl HykaAQP9tY+bQ8zSFA1n49UZBTOInSs/r5fogZ3+52IUsha7siklMX+pBl+mTFDx2t0Z Nfsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CoNckbYPyPOw79FI/5hkDMNYgaNFJcBXssk0Rr4bvzQ=; b=Fnq4wJbSoIzElqJ9HKFcwfqD00oA93uDpupruDbTnPuu52gbxC6Q/NjdtZ+re8B/PO Sr13rEwTTaRjEF64oC84bblEVIn60RMMdXi0Xx7xmneNczi/hxXi9LrQekRU/8kXDuBf idmNR+6lPZUrajNzul7WjNVW7vLClKxUq9sAyzWmzeNIA88HWjVd//qP+lkQgWKGyIXQ rCgq7S7LiFGfNsjmn0+TE07606nc8zL6xb38LN24L6OAZekmD/LTHnsafoxFvGYD1EiD +ncGSVc5RbUX3gGGEgs5OnAe1j7stGAprD6KayOxluYsxChGRmfcl7uXaQJCN1oQ4wHa Umag== X-Gm-Message-State: AOAM530FM/rDphsdyGveI2yVqxnD7SP6336QF6AAq8gpq87Vc+blR1v2 FNM87JZy2HMDtG29YQC9Iou5MN42fLQYyw== X-Google-Smtp-Source: ABdhPJxVD6X5xcBIa0rkqfWOivaFONx12PyrPIb7/o7lgd9GeMyzsZe6Mqc61kIFLngOuxGJSrLNOQ== X-Received: by 2002:aa7:8ec4:: with SMTP id b4mr12732085pfr.227.1598457511105; Wed, 26 Aug 2020 08:58:31 -0700 (PDT) Received: from localhost.localdomain ([122.167.211.143]) by smtp.gmail.com with ESMTPSA id n22sm2505555pjq.25.2020.08.26.08.58.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2020 08:58:30 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Wed, 26 Aug 2020 21:28:17 +0530 Message-Id: <20200826155818.8777-3-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200826155818.8777-1-gautamramk@gmail.com> References: <20200826155818.8777-1-gautamramk@gmail.com> Subject: [FFmpeg-devel] [RFC PATCH v6 3/4] libavcodec/j2kenc: Support for multiple layers 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 Cc: Gautam Ramakrishnan MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Gautam Ramakrishnan This patch allows setting a compression ratio and to set multiple layers. The user has to input a compression ratio for each layer. The per layer compression ration can be set as follows: -layer_rates "r1,r2,...rn" for to create 'n' layers. --- doc/encoders.texi | 16 + libavcodec/j2kenc.c | 492 +++++++++++++++++++---- libavcodec/jpeg2000.c | 12 +- libavcodec/jpeg2000.h | 10 + tests/ref/vsynth/vsynth1-jpeg2000 | 8 +- tests/ref/vsynth/vsynth1-jpeg2000-97 | 6 +- tests/ref/vsynth/vsynth2-jpeg2000 | 8 +- tests/ref/vsynth/vsynth2-jpeg2000-97 | 8 +- tests/ref/vsynth/vsynth3-jpeg2000 | 8 +- tests/ref/vsynth/vsynth3-jpeg2000-97 | 8 +- tests/ref/vsynth/vsynth_lena-jpeg2000 | 8 +- tests/ref/vsynth/vsynth_lena-jpeg2000-97 | 8 +- 12 files changed, 490 insertions(+), 102 deletions(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index fd9235a05a..481ad2fb3d 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -1401,6 +1401,22 @@ Possible values are: @end table Set to @code{lrcp} by default. +@item layer_rates @var{string} +By default, compression is done using the quality metric. This option allows for +compression using compression ratio. The compression ratio for each level could +be specified. The compression ratio of a layer @code{l} species the what ratio of +total file size is contained in the first @code{l} layers. + +Example usage: + +@example +ffmpeg -i input.bmp -c:v jpeg2000 -layer_rates "100,10,1" output.j2k +@end example + +This would compress the image to contain 3 layers, where the data contained in the +first layer would be compressed by 1000 times, compressed by 100 in the first two layers, +and shall contain all data while using all 3 layers. + @end table @section librav1e diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index 87acd2d5c9..8dab18cdd6 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -32,6 +32,7 @@ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team * Copyright (c) 2007, Callum Lerwick + * Copyright (c) 2020, Gautam Ramakrishnan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -100,6 +101,7 @@ static const int dwt_norms[2][4][10] = { // [dwt_type][band][rlevel] (multiplied typedef struct { Jpeg2000Component *comp; + double *layer_rates; } Jpeg2000Tile; typedef struct { @@ -126,12 +128,16 @@ typedef struct { Jpeg2000QuantStyle qntsty; Jpeg2000Tile *tile; + int layer_rates[100]; + uint8_t compression_rate_enc; ///< Is compression done using compression ratio? int format; int pred; int sop; int eph; int prog; + int nlayers; + char *lr_str; } Jpeg2000EncoderContext; @@ -334,7 +340,7 @@ static int put_cod(Jpeg2000EncoderContext *s) bytestream_put_byte(&s->buf, scod); // Scod // SGcod bytestream_put_byte(&s->buf, s->prog); // progression level - bytestream_put_be16(&s->buf, 1); // num of layers + bytestream_put_be16(&s->buf, s->nlayers); // num of layers if(s->avctx->pix_fmt == AV_PIX_FMT_YUV444P){ bytestream_put_byte(&s->buf, 0); // unspecified }else{ @@ -413,6 +419,31 @@ static uint8_t *put_sot(Jpeg2000EncoderContext *s, int tileno) return psotptr; } +static void compute_rates(Jpeg2000EncoderContext* s) +{ + int i, j; + int layno, compno; + for (i = 0; i < s->numYtiles; i++) { + for (j = 0; j < s->numXtiles; j++) { + Jpeg2000Tile *tile = &s->tile[s->numXtiles * i + j]; + for (compno = 0; compno < s->ncomponents; compno++) { + int tilew = tile->comp[compno].coord[0][1] - tile->comp[compno].coord[0][0]; + int tileh = tile->comp[compno].coord[1][1] - tile->comp[compno].coord[1][0]; + int scale = (compno?1 << s->chroma_shift[0]:1) * (compno?1 << s->chroma_shift[1]:1); + for (layno = 0; layno < s->nlayers; layno++) { + if (s->layer_rates[layno] > 0) { + tile->layer_rates[layno] += (double)(tilew * tileh) * s->ncomponents * s->cbps[compno] / + (double)(s->layer_rates[layno] * 8 * scale); + } else { + tile->layer_rates[layno] = 0.0; + } + } + } + } + } + +} + /** * compute the sizes of tiles, resolution levels, bands, etc. * allocate memory for them @@ -437,6 +468,11 @@ static int init_tiles(Jpeg2000EncoderContext *s) tile->comp = av_mallocz_array(s->ncomponents, sizeof(Jpeg2000Component)); if (!tile->comp) return AVERROR(ENOMEM); + + tile->layer_rates = av_mallocz_array(s->nlayers, sizeof(*tile->layer_rates)); + if (!tile->layer_rates) + return AVERROR(ENOMEM); + for (compno = 0; compno < s->ncomponents; compno++){ Jpeg2000Component *comp = tile->comp + compno; int ret, i, j; @@ -461,6 +497,7 @@ static int init_tiles(Jpeg2000EncoderContext *s) return ret; } } + compute_rates(s); return 0; } @@ -703,6 +740,8 @@ static void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg20 } cblk->passes[passno].rate = ff_mqc_flush_to(&t1->mqc, cblk->passes[passno].flushed, &cblk->passes[passno].flushed_len); + cblk->passes[passno].rate -= cblk->passes[passno].flushed_len; + wmsedec += (int64_t)nmsedec << (2*bpno); cblk->passes[passno].disto = wmsedec; @@ -714,8 +753,10 @@ static void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg20 cblk->npasses = passno; cblk->ninclpasses = passno; - if (passno) + if (passno) { cblk->passes[passno-1].rate = ff_mqc_flush_to(&t1->mqc, cblk->passes[passno-1].flushed, &cblk->passes[passno-1].flushed_len); + cblk->passes[passno-1].rate -= cblk->passes[passno-1].flushed_len; + } } /* tier-2 routines: */ @@ -735,10 +776,12 @@ static void putnumpasses(Jpeg2000EncoderContext *s, int n) } -static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, int precno, - uint8_t *expn, int numgbits, int packetno) +static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, int layno, + int precno, uint8_t *expn, int numgbits, int packetno, + int nlayers) { int bandno, empty = 1; + int i; // init bitstream *s->buf = 0; s->bit_index = 0; @@ -750,22 +793,65 @@ static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, in } // header + if (!layno) { + for (bandno = 0; bandno < rlevel->nbands; bandno++) { + Jpeg2000Band *band = rlevel->band + bandno; + if (band->coord[0][0] < band->coord[0][1] + && band->coord[1][0] < band->coord[1][1]) { + Jpeg2000Prec *prec = band->prec + precno; + int nb_cblks = prec->nb_codeblocks_height * prec->nb_codeblocks_width; + int pos; + ff_tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height); + ff_tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height); + for (pos = 0; pos < nb_cblks; pos++) { + Jpeg2000Cblk *cblk = &prec->cblk[pos]; + prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - cblk->nonzerobits; + cblk->incl = 0; + cblk->lblock = 3; + tag_tree_update(prec->zerobits + pos); + for (i = 0; i < nlayers; i++) { + if (cblk->layers[i].npasses > 0) { + prec->cblkincl[pos].val = i; + break; + } + } + if (i == nlayers) + prec->cblkincl[pos].val = i; + tag_tree_update(prec->cblkincl + pos); + } + } + } + } + // is the packet empty? for (bandno = 0; bandno < rlevel->nbands; bandno++){ - if (rlevel->band[bandno].coord[0][0] < rlevel->band[bandno].coord[0][1] - && rlevel->band[bandno].coord[1][0] < rlevel->band[bandno].coord[1][1]){ - empty = 0; - break; + Jpeg2000Band *band = rlevel->band + bandno; + if (band->coord[0][0] < band->coord[0][1] + && band->coord[1][0] < band->coord[1][1]) { + Jpeg2000Prec *prec = band->prec + precno; + int nb_cblks = prec->nb_codeblocks_height * prec->nb_codeblocks_width; + int pos; + for (pos = 0; pos < nb_cblks; pos++) { + Jpeg2000Cblk *cblk = &prec->cblk[pos]; + if (cblk->layers[layno].npasses) { + empty = 0; + break; + } + } + if (!empty) + break; } } put_bits(s, !empty, 1); if (empty){ j2k_flush(s); + if (s->eph) + bytestream_put_be16(&s->buf, JPEG2000_EPH); return 0; } - for (bandno = 0; bandno < rlevel->nbands; bandno++){ + for (bandno = 0; bandno < rlevel->nbands; bandno++) { Jpeg2000Band *band = rlevel->band + bandno; Jpeg2000Prec *prec = band->prec + precno; int yi, xi, pos; @@ -775,42 +861,46 @@ static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, in || band->coord[1][0] == band->coord[1][1]) continue; - for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++){ - for (xi = 0; xi < cblknw; xi++, pos++){ - prec->cblkincl[pos].val = prec->cblk[yi * cblknw + xi].ninclpasses == 0; - tag_tree_update(prec->cblkincl + pos); - prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - prec->cblk[yi * cblknw + xi].nonzerobits; - tag_tree_update(prec->zerobits + pos); - } - } - - for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++){ + for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++) { for (xi = 0; xi < cblknw; xi++, pos++){ - int pad = 0, llen, length; + int llen = 0, length; Jpeg2000Cblk *cblk = prec->cblk + yi * cblknw + xi; if (s->buf_end - s->buf < 20) // approximately return -1; // inclusion information - tag_tree_code(s, prec->cblkincl + pos, 1); - if (!cblk->ninclpasses) + if (!cblk->incl) + tag_tree_code(s, prec->cblkincl + pos, layno + 1); + else { + put_bits(s, cblk->layers[layno].npasses > 0, 1); + } + + if (!cblk->layers[layno].npasses) continue; + // zerobits information - tag_tree_code(s, prec->zerobits + pos, 100); + if (!cblk->incl) { + tag_tree_code(s, prec->zerobits + pos, 100); + cblk->incl = 1; + } + // number of passes - putnumpasses(s, cblk->ninclpasses); + putnumpasses(s, cblk->layers[layno].npasses); - length = cblk->passes[cblk->ninclpasses-1].rate; - llen = av_log2(length) - av_log2(cblk->ninclpasses) - 2; - if (llen < 0){ - pad = -llen; - llen = 0; + length = cblk->layers[layno].data_len; + if (layno == nlayers - 1 && cblk->layers[layno].cum_passes){ + length += cblk->passes[cblk->layers[layno].cum_passes-1].flushed_len; } + if (cblk->lblock + av_log2(cblk->layers[layno].npasses) < av_log2(length) + 1) { + llen = av_log2(length) + 1 - cblk->lblock - av_log2(cblk->layers[layno].npasses); + } + // length of code block + cblk->lblock += llen; put_bits(s, 1, llen); put_bits(s, 0, 1); - put_num(s, length, av_log2(length)+1+pad); + put_num(s, length, cblk->lblock + av_log2(cblk->layers[layno].npasses)); } } } @@ -819,21 +909,22 @@ static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, in bytestream_put_be16(&s->buf, JPEG2000_EPH); } - for (bandno = 0; bandno < rlevel->nbands; bandno++){ + for (bandno = 0; bandno < rlevel->nbands; bandno++) { Jpeg2000Band *band = rlevel->band + bandno; Jpeg2000Prec *prec = band->prec + precno; int yi, cblknw = prec->nb_codeblocks_width; - for (yi =0; yi < prec->nb_codeblocks_height; yi++){ + for (yi =0; yi < prec->nb_codeblocks_height; yi++) { int xi; for (xi = 0; xi < cblknw; xi++){ Jpeg2000Cblk *cblk = prec->cblk + yi * cblknw + xi; - if (cblk->ninclpasses){ - if (s->buf_end - s->buf < cblk->passes[cblk->ninclpasses-1].rate) + if (cblk->layers[layno].npasses) { + if (s->buf_end - s->buf < cblk->layers[layno].data_len + 2) return -1; - bytestream_put_buffer(&s->buf, cblk->data + 1, cblk->passes[cblk->ninclpasses-1].rate - - cblk->passes[cblk->ninclpasses-1].flushed_len); - bytestream_put_buffer(&s->buf, cblk->passes[cblk->ninclpasses-1].flushed, - cblk->passes[cblk->ninclpasses-1].flushed_len); + bytestream_put_buffer(&s->buf, cblk->layers[layno].data_start + 1, cblk->layers[layno].data_len); + if (layno == nlayers - 1 && cblk->layers[layno].cum_passes) { + bytestream_put_buffer(&s->buf, cblk->passes[cblk->layers[layno].cum_passes-1].flushed, + cblk->passes[cblk->layers[layno].cum_passes-1].flushed_len); + } } } } @@ -841,9 +932,9 @@ static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, in return 0; } -static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno) +static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno, int nlayers) { - int compno, reslevelno, ret; + int compno, reslevelno, layno, ret; Jpeg2000CodingStyle *codsty = &s->codsty; Jpeg2000QuantStyle *qntsty = &s->qntsty; int packetno = 0; @@ -862,27 +953,31 @@ static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int til // lay-rlevel-comp-pos progression switch (s->prog) { case JPEG2000_PGOD_LRCP: - for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ - for (compno = 0; compno < s->ncomponents; compno++){ - int precno; - Jpeg2000ResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno; - for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ - if ((ret = encode_packet(s, reslevel, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), - qntsty->nguardbits, packetno++)) < 0) - return ret; + for (layno = 0; layno < nlayers; layno++) { + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ + for (compno = 0; compno < s->ncomponents; compno++){ + int precno; + Jpeg2000ResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno; + for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ + if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), + qntsty->nguardbits, packetno++, nlayers)) < 0) + return ret; + } } } } break; case JPEG2000_PGOD_RLCP: for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ - for (compno = 0; compno < s->ncomponents; compno++){ - int precno; - Jpeg2000ResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno; - for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ - if ((ret = encode_packet(s, reslevel, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), - qntsty->nguardbits, packetno++)) < 0) - return ret; + for (layno = 0; layno < nlayers; layno++) { + for (compno = 0; compno < s->ncomponents; compno++){ + int precno; + Jpeg2000ResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno; + for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ + if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), + qntsty->nguardbits, packetno++, nlayers)) < 0) + return ret; + } } } } @@ -937,10 +1032,11 @@ static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int til prcx, prcy, reslevel->num_precincts_x, reslevel->num_precincts_y); continue; } - - if ((ret = encode_packet(s, reslevel, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), - qntsty->nguardbits, packetno++)) < 0) - return ret; + for (layno = 0; layno < nlayers; layno++) { + if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), + qntsty->nguardbits, packetno++, nlayers)) < 0) + return ret; + } } } } @@ -1003,9 +1099,11 @@ static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int til prcx, prcy, reslevel->num_precincts_x, reslevel->num_precincts_y); continue; } - if ((ret = encode_packet(s, reslevel, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), - qntsty->nguardbits, packetno++)) < 0) - return ret; + for (layno = 0; layno < nlayers; layno++) { + if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), + qntsty->nguardbits, packetno++, nlayers)) < 0) + return ret; + } } } } @@ -1064,9 +1162,11 @@ static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int til prcx, prcy, reslevel->num_precincts_x, reslevel->num_precincts_y); continue; } - if ((ret = encode_packet(s, reslevel, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), - qntsty->nguardbits, packetno++)) < 0) - return ret; + for (layno = 0; layno < nlayers; layno++) { + if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), + qntsty->nguardbits, packetno++, nlayers)) < 0) + return ret; + } } } } @@ -1078,6 +1178,174 @@ static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int til return 0; } +static void makelayer(Jpeg2000EncoderContext *s, int layno, double thresh, Jpeg2000Tile* tile, int final) +{ + int compno, resno, bandno, precno, cblkno; + int passno; + + for (compno = 0; compno < s->ncomponents; compno++) { + Jpeg2000Component *comp = &tile->comp[compno]; + + for (resno = 0; resno < s->codsty.nreslevels; resno++) { + Jpeg2000ResLevel *reslevel = comp->reslevel + resno; + + for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ + for (bandno = 0; bandno < reslevel->nbands ; bandno++){ + Jpeg2000Band *band = reslevel->band + bandno; + Jpeg2000Prec *prec = band->prec + precno; + + for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){ + Jpeg2000Cblk *cblk = prec->cblk + cblkno; + Jpeg2000Layer *layer = &cblk->layers[layno]; + int n; + + if (layno == 0) { + cblk->ninclpasses = 0; + } + + n = cblk->ninclpasses; + + if (thresh < 0) { + n = cblk->npasses; + } else { + for (passno = cblk->ninclpasses; passno < cblk->npasses; passno++) { + int32_t dr; + double dd; + Jpeg2000Pass *pass = &cblk->passes[passno]; + + if (n == 0) { + dr = pass->rate; + dd = pass->disto; + } else { + dr = pass->rate - cblk->passes[n - 1].rate; + dd = pass->disto - cblk->passes[n-1].disto; + } + + if (!dr) { + if (dd != 0.0) { + n = passno + 1; + } + continue; + } + + if (thresh - (dd / dr) < DBL_EPSILON) + n = passno + 1; + } + } + layer->npasses = n - cblk->ninclpasses; + layer->cum_passes = n; + + if (layer->npasses == 0) { + layer->disto = 0; + layer->data_len = 0; + continue; + } + + if (cblk->ninclpasses == 0) { + layer->data_len = cblk->passes[n - 1].rate; + layer->data_start = cblk->data; + layer->disto = cblk->passes[n - 1].disto; + } else { + layer->data_len = cblk->passes[n - 1].rate - cblk->passes[cblk->ninclpasses - 1].rate; + layer->data_start = cblk->data + cblk->passes[cblk->ninclpasses - 1].rate; + layer->disto = cblk->passes[n - 1].disto - + cblk->passes[cblk->ninclpasses - 1].disto; + } + if (final) { + cblk->ninclpasses = n; + } + } + } + } + } + } +} + +static void makelayers(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) +{ + int precno, compno, reslevelno, bandno, cblkno, lev, passno, layno; + int i; + double min = DBL_MAX; + double max = 0; + double thresh; + int tile_disto = 0; + + Jpeg2000CodingStyle *codsty = &s->codsty; + + for (compno = 0; compno < s->ncomponents; compno++){ + Jpeg2000Component *comp = tile->comp + compno; + + for (reslevelno = 0, lev = codsty->nreslevels-1; reslevelno < codsty->nreslevels; reslevelno++, lev--){ + Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; + + for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ + for (bandno = 0; bandno < reslevel->nbands ; bandno++){ + Jpeg2000Band *band = reslevel->band + bandno; + Jpeg2000Prec *prec = band->prec + precno; + + for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){ + Jpeg2000Cblk *cblk = prec->cblk + cblkno; + for (passno = 0; passno < cblk->npasses; passno++) { + Jpeg2000Pass *pass = &cblk->passes[passno]; + int dr; + double dd, drslope; + + tile_disto += pass->disto; + if (passno == 0) { + dr = (int32_t)pass->rate; + dd = pass->disto; + } else { + dr = (int32_t)(pass->rate - cblk->passes[passno - 1].rate); + dd = pass->disto - cblk->passes[passno - 1].disto; + } + + if (dr <= 0) + continue; + + drslope = dd / dr; + if (drslope < min) + min = drslope; + + if (drslope > max) + max = drslope; + } + } + } + } + } + } + + for (layno = 0; layno < s->nlayers; layno++) { + double lo = min; + double hi = max; + double stable_thresh = 0.0; + double good_thresh = 0.0; + if (!s->layer_rates[layno]) { + good_thresh = -1.0; + } else { + for (i = 0; i < 128; i++) { + uint8_t *stream_pos = s->buf; + int ret; + thresh = (lo + hi) / 2; + makelayer(s, layno, thresh, tile, 0); + ret = encode_packets(s, tile, (int)(tile - s->tile), layno + 1); + memset(stream_pos, 0, s->buf - stream_pos); + if ((s->buf - stream_pos > ceil(tile->layer_rates[layno])) || ret < 0) { + lo = thresh; + s->buf = stream_pos; + continue; + } + hi = thresh; + stable_thresh = thresh; + s->buf = stream_pos; + } + } + if (good_thresh >= 0.0) + good_thresh = stable_thresh == 0.0 ? thresh : stable_thresh; + makelayer(s, layno, good_thresh, tile, 1); + } +} + static int getcut(Jpeg2000Cblk *cblk, int64_t lambda, int dwt_norm) { int passno, res = 0; @@ -1086,9 +1354,9 @@ static int getcut(Jpeg2000Cblk *cblk, int64_t lambda, int dwt_norm) int64_t dd; dr = cblk->passes[passno].rate - - (res ? cblk->passes[res-1].rate:0); + - (res ? cblk->passes[res-1].rate : 0); dd = cblk->passes[passno].disto - - (res ? cblk->passes[res-1].disto:0); + - (res ? cblk->passes[res-1].disto : 0); if (((dd * dwt_norm) >> WMSEDEC_SHIFT) * dwt_norm >= dr * lambda) res = passno+1; @@ -1118,6 +1386,11 @@ static void truncpasses(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) cblk->ninclpasses = getcut(cblk, s->lambda, (int64_t)dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 15); + cblk->layers[0].data_start = cblk->data; + cblk->layers[0].cum_passes = cblk->ninclpasses; + cblk->layers[0].npasses = cblk->ninclpasses; + if (cblk->ninclpasses) + cblk->layers[0].data_len = cblk->passes[cblk->ninclpasses - 1].rate; } } } @@ -1205,8 +1478,12 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno } av_log(s->avctx, AV_LOG_DEBUG, "rate control\n"); - truncpasses(s, tile); - if ((ret = encode_packets(s, tile, tileno)) < 0) + if (s->compression_rate_enc) + makelayers(s, tile); + else + truncpasses(s, tile); + + if ((ret = encode_packets(s, tile, tileno, s->nlayers)) < 0) return ret; av_log(s->avctx, AV_LOG_DEBUG, "after rate control\n"); return 0; @@ -1223,6 +1500,7 @@ static void cleanup(Jpeg2000EncoderContext *s) ff_jpeg2000_cleanup(comp, codsty); } av_freep(&s->tile[tileno].comp); + av_freep(&s->tile[tileno].layer_rates); } av_freep(&s->tile); } @@ -1381,6 +1659,74 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static int inline check_number(char* st, int* ret) { + size_t stlen; + int i; + *ret = 0; + + if (!st) + return AVERROR_INVALIDDATA; + + stlen = strlen(st); + if (stlen == 0) { + return AVERROR_INVALIDDATA; + } + for (i = 0; i < stlen; i++) { + if (st[i] >= '0' && st[i] <= '9') { + *ret = (*ret) * 10 + (st[i] - '0'); + } else { + return AVERROR_INVALIDDATA; + } + } + return 0; +} + +static int parse_layer_rates(Jpeg2000EncoderContext *s) +{ + int i; + char* token; + int rate; + int nlayers = 0; + if (!s->lr_str) { + s->nlayers = 1; + s->layer_rates[0] = 0; + s->compression_rate_enc = 0; + return 0; + } + + token = strtok(s->lr_str, ","); + if (!check_number(token, &rate)) { + s->layer_rates[0] = rate <= 1 ? 0:rate; + nlayers++; + } else { + return AVERROR_INVALIDDATA; + } + + while (1) { + token = strtok(NULL, ","); + if (!token) + break; + if (!check_number(token, &rate)) { + if (nlayers >= 100) { + return AVERROR_INVALIDDATA; + } + s->layer_rates[nlayers] = rate <= 1 ? 0:rate; + nlayers++; + } else { + return AVERROR_INVALIDDATA; + } + } + + for (i = 1; i < nlayers; i++) { + if (s->layer_rates[i] >= s->layer_rates[i-1]) { + return AVERROR_INVALIDDATA; + } + } + s->nlayers = nlayers; + s->compression_rate_enc = 1; + return 0; +} + static av_cold int j2kenc_init(AVCodecContext *avctx) { int i, ret; @@ -1390,6 +1736,12 @@ static av_cold int j2kenc_init(AVCodecContext *avctx) s->avctx = avctx; av_log(s->avctx, AV_LOG_DEBUG, "init\n"); + if (parse_layer_rates(s)) { + av_log(s, AV_LOG_WARNING, "Layer rates invalid. Encoding with 1 layer based on quality metric.\n"); + s->nlayers = 1; + s->layer_rates[0] = 0; + s->compression_rate_enc = 0; + } #if FF_API_PRIVATE_OPT FF_DISABLE_DEPRECATION_WARNINGS @@ -1410,6 +1762,7 @@ FF_ENABLE_DEPRECATION_WARNINGS memset(codsty->log2_prec_heights, 15, sizeof(codsty->log2_prec_heights)); codsty->nreslevels2decode= codsty->nreslevels = 7; + codsty->nlayers = s->nlayers; codsty->log2_cblk_width = 4; codsty->log2_cblk_height = 4; codsty->transform = s->pred ? FF_DWT53 : FF_DWT97_INT; @@ -1491,6 +1844,7 @@ static const AVOption options[] = { { "rpcl", NULL, OFFSET(prog), AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_RPCL }, 0, 0, VE, "prog" }, { "pcrl", NULL, OFFSET(prog), AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_PCRL }, 0, 0, VE, "prog" }, { "cprl", NULL, OFFSET(prog), AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_CPRL }, 0, 0, VE, "prog" }, + { "layer_rates", "Layer Rates", OFFSET(lr_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VE }, { NULL } }; diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index 3d3e7ec313..6501de0d04 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -261,9 +261,11 @@ static void init_band_stepsize(AVCodecContext *avctx, band->f_stepsize *= 0.5; } -static int init_prec(Jpeg2000Band *band, +static int init_prec(AVCodecContext *avctx, + Jpeg2000Band *band, Jpeg2000ResLevel *reslevel, Jpeg2000Component *comp, + Jpeg2000CodingStyle *codsty, int precno, int bandno, int reslevelno, int log2_band_prec_width, int log2_band_prec_height) @@ -366,6 +368,11 @@ static int init_prec(Jpeg2000Band *band, cblk->lblock = 3; cblk->length = 0; cblk->npasses = 0; + if (av_codec_is_encoder(avctx->codec)) { + cblk->layers = av_mallocz_array(codsty->nlayers, sizeof(*cblk->layers)); + if (!cblk->layers) + return AVERROR(ENOMEM); + } } return 0; @@ -439,7 +446,7 @@ static int init_band(AVCodecContext *avctx, return AVERROR(ENOMEM); for (precno = 0; precno < nb_precincts; precno++) { - ret = init_prec(band, reslevel, comp, + ret = init_prec(avctx, band, reslevel, comp, codsty, precno, bandno, reslevelno, log2_band_prec_width, log2_band_prec_height); if (ret < 0) @@ -614,6 +621,7 @@ void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty) av_freep(&cblk->passes); av_freep(&cblk->lengthinc); av_freep(&cblk->data_start); + av_freep(&cblk->layers); } av_freep(&prec->cblk); } diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index ad58b1ae88..a7ba8aa7f3 100644 --- a/libavcodec/jpeg2000.h +++ b/libavcodec/jpeg2000.h @@ -162,10 +162,19 @@ typedef struct Jpeg2000Pass { int flushed_len; } Jpeg2000Pass; +typedef struct Jpeg2000Layer { + uint8_t *data_start; + int data_len; + int npasses; + double disto; + int cum_passes; +} Jpeg2000Layer; + typedef struct Jpeg2000Cblk { uint8_t npasses; uint8_t ninclpasses; // number coding of passes included in codestream uint8_t nonzerobits; + uint8_t incl; uint16_t length; uint16_t *lengthinc; uint8_t nb_lengthinc; @@ -176,6 +185,7 @@ typedef struct Jpeg2000Cblk { int nb_terminationsinc; int *data_start; Jpeg2000Pass *passes; + Jpeg2000Layer *layers; int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} } Jpeg2000Cblk; // code block diff --git a/tests/ref/vsynth/vsynth1-jpeg2000 b/tests/ref/vsynth/vsynth1-jpeg2000 index 48accf500a..5081507459 100644 --- a/tests/ref/vsynth/vsynth1-jpeg2000 +++ b/tests/ref/vsynth/vsynth1-jpeg2000 @@ -1,4 +1,4 @@ -d2a06ad916711d29b30977a06335bb76 *tests/data/fate/vsynth1-jpeg2000.avi -2265698 tests/data/fate/vsynth1-jpeg2000.avi -15a8e49f6fd014193bbafd72f84936c7 *tests/data/fate/vsynth1-jpeg2000.out.rawvideo -stddev: 5.36 PSNR: 33.55 MAXDIFF: 61 bytes: 7603200/ 7603200 +dd66b25f2ebc965eae4c29cfacdd960f *tests/data/fate/vsynth1-jpeg2000.avi +2274950 tests/data/fate/vsynth1-jpeg2000.avi +b7f48a8965f78011c76483277befc6fc *tests/data/fate/vsynth1-jpeg2000.out.rawvideo +stddev: 5.35 PSNR: 33.56 MAXDIFF: 59 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-jpeg2000-97 b/tests/ref/vsynth/vsynth1-jpeg2000-97 index 33b3299ad1..7e18f20e25 100644 --- a/tests/ref/vsynth/vsynth1-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth1-jpeg2000-97 @@ -1,4 +1,4 @@ -8bb707e596f97451fd325dec2dd610a7 *tests/data/fate/vsynth1-jpeg2000-97.avi -3654620 tests/data/fate/vsynth1-jpeg2000-97.avi -5073771a78e1f5366a7eb0df341662fc *tests/data/fate/vsynth1-jpeg2000-97.out.rawvideo +f22ad99de77f8f4382c6cf10d5af42b5 *tests/data/fate/vsynth1-jpeg2000-97.avi +3661422 tests/data/fate/vsynth1-jpeg2000-97.avi +a2262f1da2f49bc196b780a6b47ec4e8 *tests/data/fate/vsynth1-jpeg2000-97.out.rawvideo stddev: 4.23 PSNR: 35.59 MAXDIFF: 53 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-jpeg2000 b/tests/ref/vsynth/vsynth2-jpeg2000 index 094f416882..7b70e99ed9 100644 --- a/tests/ref/vsynth/vsynth2-jpeg2000 +++ b/tests/ref/vsynth/vsynth2-jpeg2000 @@ -1,4 +1,4 @@ -6c2f979e4a33a36f36aec86f2d464143 *tests/data/fate/vsynth2-jpeg2000.avi -1494516 tests/data/fate/vsynth2-jpeg2000.avi -36afd96d6e55bc83166fd615351ba366 *tests/data/fate/vsynth2-jpeg2000.out.rawvideo -stddev: 5.00 PSNR: 34.15 MAXDIFF: 59 bytes: 7603200/ 7603200 +49df1372d20dae57b4ff28ac4d81bb78 *tests/data/fate/vsynth2-jpeg2000.avi +1551520 tests/data/fate/vsynth2-jpeg2000.avi +64fadc87447268cf90503cb294db7f61 *tests/data/fate/vsynth2-jpeg2000.out.rawvideo +stddev: 4.91 PSNR: 34.29 MAXDIFF: 55 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-jpeg2000-97 b/tests/ref/vsynth/vsynth2-jpeg2000-97 index 38153ea0ea..3400760573 100644 --- a/tests/ref/vsynth/vsynth2-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth2-jpeg2000-97 @@ -1,4 +1,4 @@ -2e43f004a55f4a55a19c4b79fc8e8743 *tests/data/fate/vsynth2-jpeg2000-97.avi -2448706 tests/data/fate/vsynth2-jpeg2000-97.avi -a6e2453118a0de135836a868b2ca0e60 *tests/data/fate/vsynth2-jpeg2000-97.out.rawvideo -stddev: 3.23 PSNR: 37.94 MAXDIFF: 29 bytes: 7603200/ 7603200 +8443e3ae43675212be9a8274cfe5d5be *tests/data/fate/vsynth2-jpeg2000-97.avi +2484530 tests/data/fate/vsynth2-jpeg2000-97.avi +1f63c8b065e847e4c63d57ce23442ea8 *tests/data/fate/vsynth2-jpeg2000-97.out.rawvideo +stddev: 3.21 PSNR: 37.99 MAXDIFF: 26 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth3-jpeg2000 b/tests/ref/vsynth/vsynth3-jpeg2000 index a1e3a8090a..2c3a0d9026 100644 --- a/tests/ref/vsynth/vsynth3-jpeg2000 +++ b/tests/ref/vsynth/vsynth3-jpeg2000 @@ -1,4 +1,4 @@ -0b8aa8113c10772cffff60f9c8ffd902 *tests/data/fate/vsynth3-jpeg2000.avi -65548 tests/data/fate/vsynth3-jpeg2000.avi -2d8bd94d558755c47d7e23fd9556e164 *tests/data/fate/vsynth3-jpeg2000.out.rawvideo -stddev: 5.48 PSNR: 33.34 MAXDIFF: 47 bytes: 86700/ 86700 +548df443acb32593455bbcd8f531c00b *tests/data/fate/vsynth3-jpeg2000.avi +67658 tests/data/fate/vsynth3-jpeg2000.avi +098f5980667e1fcd50452b1dc1a74f61 *tests/data/fate/vsynth3-jpeg2000.out.rawvideo +stddev: 5.47 PSNR: 33.36 MAXDIFF: 48 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-jpeg2000-97 b/tests/ref/vsynth/vsynth3-jpeg2000-97 index 191956f580..1b805f04ad 100644 --- a/tests/ref/vsynth/vsynth3-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth3-jpeg2000-97 @@ -1,4 +1,4 @@ -b6c88a623c3296ca945346d2203f0af0 *tests/data/fate/vsynth3-jpeg2000-97.avi -83870 tests/data/fate/vsynth3-jpeg2000-97.avi -0cd707bfb1bbe5312b00c094f695b1fa *tests/data/fate/vsynth3-jpeg2000-97.out.rawvideo -stddev: 4.52 PSNR: 35.02 MAXDIFF: 47 bytes: 86700/ 86700 +494464d224d5aa2726bc6a8630a390aa *tests/data/fate/vsynth3-jpeg2000-97.avi +86016 tests/data/fate/vsynth3-jpeg2000-97.avi +8def36ad1413ab3a5c2af2e1af4603f9 *tests/data/fate/vsynth3-jpeg2000-97.out.rawvideo +stddev: 4.51 PSNR: 35.04 MAXDIFF: 47 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth_lena-jpeg2000 b/tests/ref/vsynth/vsynth_lena-jpeg2000 index 72550eb816..2b4560ab54 100644 --- a/tests/ref/vsynth/vsynth_lena-jpeg2000 +++ b/tests/ref/vsynth/vsynth_lena-jpeg2000 @@ -1,4 +1,4 @@ -1f2cf6061c78905b8011091a9a7c425f *tests/data/fate/vsynth_lena-jpeg2000.avi -1138054 tests/data/fate/vsynth_lena-jpeg2000.avi -955653ca7a08447e7b1501b444f24562 *tests/data/fate/vsynth_lena-jpeg2000.out.rawvideo -stddev: 4.40 PSNR: 35.25 MAXDIFF: 58 bytes: 7603200/ 7603200 +e4cf380b198e6bcb00ec338914f6ebb3 *tests/data/fate/vsynth_lena-jpeg2000.avi +1202516 tests/data/fate/vsynth_lena-jpeg2000.avi +39a2c5b61cd0cf2821c6fb4cceba2fa8 *tests/data/fate/vsynth_lena-jpeg2000.out.rawvideo +stddev: 4.30 PSNR: 35.45 MAXDIFF: 45 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-jpeg2000-97 b/tests/ref/vsynth/vsynth_lena-jpeg2000-97 index 5c12665b66..1343dbc21b 100644 --- a/tests/ref/vsynth/vsynth_lena-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth_lena-jpeg2000-97 @@ -1,4 +1,4 @@ -e5a756e97910420c90e76259c56261cb *tests/data/fate/vsynth_lena-jpeg2000-97.avi -1918956 tests/data/fate/vsynth_lena-jpeg2000-97.avi -93a4ba0c230f2430a813df594676e58a *tests/data/fate/vsynth_lena-jpeg2000-97.out.rawvideo -stddev: 2.84 PSNR: 39.04 MAXDIFF: 28 bytes: 7603200/ 7603200 +29dd43765363e17179c2de4167b32399 *tests/data/fate/vsynth_lena-jpeg2000-97.avi +1958334 tests/data/fate/vsynth_lena-jpeg2000-97.avi +1b97333a8dc115a5ba609b0070d89d4d *tests/data/fate/vsynth_lena-jpeg2000-97.out.rawvideo +stddev: 2.82 PSNR: 39.10 MAXDIFF: 24 bytes: 7603200/ 7603200 From patchwork Wed Aug 26 15:58:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21934 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 CC64644A7B7 for ; Wed, 26 Aug 2020 18:58:43 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B25C468AC1E; Wed, 26 Aug 2020 18:58:43 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 48590687FAE for ; Wed, 26 Aug 2020 18:58:35 +0300 (EEST) Received: by mail-pf1-f171.google.com with SMTP id u128so1200862pfb.6 for ; Wed, 26 Aug 2020 08:58:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=sTovshxO3O0PjBFh5U2vcNKpc/n1IVFPHVo133UL9D0=; b=El7bFQRmN1DodECpzekBuig8nQSSr+H2GTPXN9I66PBA0U3Uz0ksg1UDv2UVj9Dhd7 RXtEzzX19XkAHLRHbt7DvPu0Fx+H+LiNDoEN3nzupZHhzsejpOTV15mVg4lmfGu+/S7o j76m5Ir1PGjcNqt3jcpBVxKiv0y6TK+6EX91wS8Z8Ton1kq9fNyL1+ChYCV64Xz884yx EMjRVKsdRQ/y3qoL2xiNQuyg5q1reQtgTaTUhx5lUepPyL742jo7qk6r4x8cDF2IeJWJ X3WLJH3wLIIxTXFwy9Dy7jydSNBsEcbyDQKHJYwmb/PuV7vL3OYNZE8tV406IhGSNTkm /Hcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=sTovshxO3O0PjBFh5U2vcNKpc/n1IVFPHVo133UL9D0=; b=ZFS5XvuCbV7G0tVKaShMajyb1BlSO/dVaVoszylcrDklVhse+gPVUT2wgr6vyMMySQ BZ3CUBozeN7NLxFhdL6zvuvysu127aS7ijSmMnpnq86Y44Q979DhNtyLoAcoE0SOtL+I A0RbgZ8EWSWBY7AN0lZRIjNwSYXypAZs7ZL7AwM191EulvnQmERII6b6jTWnzq3sRfjm jvwIpDn6ibCo5PVv6q9CM4NJkxZtM3rLWbv6qqJ8IMqQ9Y+7XE1OYcu0EXdsaxDpWdA3 0larFkQsZJmNV1p6yXI9mV8NY9q/C4b1mPzS5CcbdfpqvYRhEL+eHkSCWtMQr1Kf2YE0 ojjg== X-Gm-Message-State: AOAM532TUDku3P4H3RkNBk56U2kLFqmHx8FsZzUhbCbxIaQzRAReB3qj l/dMqkIG8hj2Z6JFENYsIse5ociI0XpJ8Q== X-Google-Smtp-Source: ABdhPJz40Pq2eFNa2FC6aRWabMAn12FCO3F60KYZJKf35a2veHOJXaNvkBcEVr+mr+0blLnEdsgO2g== X-Received: by 2002:a05:6a00:851:: with SMTP id q17mr12835550pfk.214.1598457513138; Wed, 26 Aug 2020 08:58:33 -0700 (PDT) Received: from localhost.localdomain ([122.167.211.143]) by smtp.gmail.com with ESMTPSA id n22sm2505555pjq.25.2020.08.26.08.58.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2020 08:58:32 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Wed, 26 Aug 2020 21:28:18 +0530 Message-Id: <20200826155818.8777-4-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200826155818.8777-1-gautamramk@gmail.com> References: <20200826155818.8777-1-gautamramk@gmail.com> Subject: [FFmpeg-devel] [RFC PATCH v6 4/4] libavcodec/jpeg2000: fix tag tree reset 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 Cc: Gautam Ramakrishnan MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Gautam Ramakrishnan The implementation of the tag tree did not set the correct reset value for the encoder. This lead to inefficent tag tree being encoded. This patch fixes the implementation of the ff_tag_tree_zero() function. --- libavcodec/j2kenc.c | 4 ++-- libavcodec/jpeg2000.c | 8 ++++---- libavcodec/jpeg2000.h | 2 +- tests/ref/vsynth/vsynth1-jpeg2000 | 4 ++-- tests/ref/vsynth/vsynth1-jpeg2000-97 | 4 ++-- tests/ref/vsynth/vsynth2-jpeg2000 | 4 ++-- tests/ref/vsynth/vsynth2-jpeg2000-97 | 4 ++-- tests/ref/vsynth/vsynth3-jpeg2000 | 4 ++-- tests/ref/vsynth/vsynth3-jpeg2000-97 | 4 ++-- tests/ref/vsynth/vsynth_lena-jpeg2000 | 4 ++-- tests/ref/vsynth/vsynth_lena-jpeg2000-97 | 4 ++-- 11 files changed, 23 insertions(+), 23 deletions(-) diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index 8dab18cdd6..ed3ad73c8e 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -801,8 +801,8 @@ static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, in Jpeg2000Prec *prec = band->prec + precno; int nb_cblks = prec->nb_codeblocks_height * prec->nb_codeblocks_width; int pos; - ff_tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height); - ff_tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height); + ff_tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 99); + ff_tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 99); for (pos = 0; pos < nb_cblks; pos++) { Jpeg2000Cblk *cblk = &prec->cblk[pos]; prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - cblk->nonzerobits; diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index 6501de0d04..56d98c8a89 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -82,12 +82,12 @@ static Jpeg2000TgtNode *ff_jpeg2000_tag_tree_init(int w, int h) return res; } -void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h) +void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h, int val) { int i, siz = ff_tag_tree_size(w, h); for (i = 0; i < siz; i++) { - t[i].val = 0; + t[i].val = val; t[i].temp_val = 0; t[i].vis = 0; } @@ -575,8 +575,8 @@ void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty) Jpeg2000Band *band = rlevel->band + bandno; for(precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++) { Jpeg2000Prec *prec = band->prec + precno; - ff_tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height); - ff_tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height); + ff_tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 0); + ff_tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 0); for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) { Jpeg2000Cblk *cblk = prec->cblk + cblkno; cblk->length = 0; diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index a7ba8aa7f3..612832c872 100644 --- a/libavcodec/jpeg2000.h +++ b/libavcodec/jpeg2000.h @@ -302,6 +302,6 @@ static inline int needs_termination(int style, int passno) { } int32_t ff_tag_tree_size(int w, int h); -void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h); +void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h, int val); #endif /* AVCODEC_JPEG2000_H */ diff --git a/tests/ref/vsynth/vsynth1-jpeg2000 b/tests/ref/vsynth/vsynth1-jpeg2000 index 5081507459..f8e987f95d 100644 --- a/tests/ref/vsynth/vsynth1-jpeg2000 +++ b/tests/ref/vsynth/vsynth1-jpeg2000 @@ -1,4 +1,4 @@ -dd66b25f2ebc965eae4c29cfacdd960f *tests/data/fate/vsynth1-jpeg2000.avi -2274950 tests/data/fate/vsynth1-jpeg2000.avi +95add005faf68fcf8f16e86eab079ca2 *tests/data/fate/vsynth1-jpeg2000.avi +2263192 tests/data/fate/vsynth1-jpeg2000.avi b7f48a8965f78011c76483277befc6fc *tests/data/fate/vsynth1-jpeg2000.out.rawvideo stddev: 5.35 PSNR: 33.56 MAXDIFF: 59 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-jpeg2000-97 b/tests/ref/vsynth/vsynth1-jpeg2000-97 index 7e18f20e25..6ab5aa4237 100644 --- a/tests/ref/vsynth/vsynth1-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth1-jpeg2000-97 @@ -1,4 +1,4 @@ -f22ad99de77f8f4382c6cf10d5af42b5 *tests/data/fate/vsynth1-jpeg2000-97.avi -3661422 tests/data/fate/vsynth1-jpeg2000-97.avi +e4d03b2e3c03e56c7f831b1e662c4031 *tests/data/fate/vsynth1-jpeg2000-97.avi +3643928 tests/data/fate/vsynth1-jpeg2000-97.avi a2262f1da2f49bc196b780a6b47ec4e8 *tests/data/fate/vsynth1-jpeg2000-97.out.rawvideo stddev: 4.23 PSNR: 35.59 MAXDIFF: 53 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-jpeg2000 b/tests/ref/vsynth/vsynth2-jpeg2000 index 7b70e99ed9..d0df0099ea 100644 --- a/tests/ref/vsynth/vsynth2-jpeg2000 +++ b/tests/ref/vsynth/vsynth2-jpeg2000 @@ -1,4 +1,4 @@ -49df1372d20dae57b4ff28ac4d81bb78 *tests/data/fate/vsynth2-jpeg2000.avi -1551520 tests/data/fate/vsynth2-jpeg2000.avi +8c8a68ca748190c71b3ea43e5ab7f502 *tests/data/fate/vsynth2-jpeg2000.avi +1538736 tests/data/fate/vsynth2-jpeg2000.avi 64fadc87447268cf90503cb294db7f61 *tests/data/fate/vsynth2-jpeg2000.out.rawvideo stddev: 4.91 PSNR: 34.29 MAXDIFF: 55 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-jpeg2000-97 b/tests/ref/vsynth/vsynth2-jpeg2000-97 index 3400760573..33c1fb2425 100644 --- a/tests/ref/vsynth/vsynth2-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth2-jpeg2000-97 @@ -1,4 +1,4 @@ -8443e3ae43675212be9a8274cfe5d5be *tests/data/fate/vsynth2-jpeg2000-97.avi -2484530 tests/data/fate/vsynth2-jpeg2000-97.avi +c8f76055f59804ca72dbd66eb4db83a2 *tests/data/fate/vsynth2-jpeg2000-97.avi +2464138 tests/data/fate/vsynth2-jpeg2000-97.avi 1f63c8b065e847e4c63d57ce23442ea8 *tests/data/fate/vsynth2-jpeg2000-97.out.rawvideo stddev: 3.21 PSNR: 37.99 MAXDIFF: 26 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth3-jpeg2000 b/tests/ref/vsynth/vsynth3-jpeg2000 index 2c3a0d9026..ecc286b9a4 100644 --- a/tests/ref/vsynth/vsynth3-jpeg2000 +++ b/tests/ref/vsynth/vsynth3-jpeg2000 @@ -1,4 +1,4 @@ -548df443acb32593455bbcd8f531c00b *tests/data/fate/vsynth3-jpeg2000.avi -67658 tests/data/fate/vsynth3-jpeg2000.avi +776bf3234cbf25002f129b89baab42ea *tests/data/fate/vsynth3-jpeg2000.avi +67400 tests/data/fate/vsynth3-jpeg2000.avi 098f5980667e1fcd50452b1dc1a74f61 *tests/data/fate/vsynth3-jpeg2000.out.rawvideo stddev: 5.47 PSNR: 33.36 MAXDIFF: 48 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-jpeg2000-97 b/tests/ref/vsynth/vsynth3-jpeg2000-97 index 1b805f04ad..df10f43270 100644 --- a/tests/ref/vsynth/vsynth3-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth3-jpeg2000-97 @@ -1,4 +1,4 @@ -494464d224d5aa2726bc6a8630a390aa *tests/data/fate/vsynth3-jpeg2000-97.avi -86016 tests/data/fate/vsynth3-jpeg2000-97.avi +cd023db503f03ef72dd83e4617a90c7b *tests/data/fate/vsynth3-jpeg2000-97.avi +85606 tests/data/fate/vsynth3-jpeg2000-97.avi 8def36ad1413ab3a5c2af2e1af4603f9 *tests/data/fate/vsynth3-jpeg2000-97.out.rawvideo stddev: 4.51 PSNR: 35.04 MAXDIFF: 47 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth_lena-jpeg2000 b/tests/ref/vsynth/vsynth_lena-jpeg2000 index 2b4560ab54..88629add21 100644 --- a/tests/ref/vsynth/vsynth_lena-jpeg2000 +++ b/tests/ref/vsynth/vsynth_lena-jpeg2000 @@ -1,4 +1,4 @@ -e4cf380b198e6bcb00ec338914f6ebb3 *tests/data/fate/vsynth_lena-jpeg2000.avi -1202516 tests/data/fate/vsynth_lena-jpeg2000.avi +b8aaa45236f77a2a626791d462fd8ac1 *tests/data/fate/vsynth_lena-jpeg2000.avi +1188886 tests/data/fate/vsynth_lena-jpeg2000.avi 39a2c5b61cd0cf2821c6fb4cceba2fa8 *tests/data/fate/vsynth_lena-jpeg2000.out.rawvideo stddev: 4.30 PSNR: 35.45 MAXDIFF: 45 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-jpeg2000-97 b/tests/ref/vsynth/vsynth_lena-jpeg2000-97 index 1343dbc21b..b6f5f75f77 100644 --- a/tests/ref/vsynth/vsynth_lena-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth_lena-jpeg2000-97 @@ -1,4 +1,4 @@ -29dd43765363e17179c2de4167b32399 *tests/data/fate/vsynth_lena-jpeg2000-97.avi -1958334 tests/data/fate/vsynth_lena-jpeg2000-97.avi +b2d9525433c6300674f504922d762437 *tests/data/fate/vsynth_lena-jpeg2000-97.avi +1937232 tests/data/fate/vsynth_lena-jpeg2000-97.avi 1b97333a8dc115a5ba609b0070d89d4d *tests/data/fate/vsynth_lena-jpeg2000-97.out.rawvideo stddev: 2.82 PSNR: 39.10 MAXDIFF: 24 bytes: 7603200/ 7603200