From patchwork Tue Aug 25 04:20:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21896 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 249F444BC3D for ; Tue, 25 Aug 2020 07:20:26 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0693C68A71D; Tue, 25 Aug 2020 07:20:26 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8AB086881F1 for ; Tue, 25 Aug 2020 07:20:19 +0300 (EEST) Received: by mail-pg1-f196.google.com with SMTP id w186so3808495pgb.8 for ; Mon, 24 Aug 2020 21:20:19 -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=fw3q9lCztrHDi/hftNE7R5YgDvkkYRCdDaqiXrC5E/v3CC5lVw3wBuTbZ9oUdXTE39 9hFZlmCKdMd89P+SMXh5lrxoXgYI4SvbuuFek3u/4SWf2Fqai8O+qyKbuxqxGOymLPhM sv1w36c/BgHer+quktcLhCkOm/WlIRfgAO3H/0mWo+GdOf3bw/p3xxSmu+JMNgc/JpZq xBqOik5TMt9XFqluqbdJvqsLs4xDkpx1pzb3NEY/YVOM6Xy4hPi+kD/Pocx87Emfk+Ho kP3XybpNmUZRJFKZdQQZl7VlJA41eeXFk6An7kkabF63vSMhDE0l1uQMLHqEiFS7sCM/ 1bxw== 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=RY9VsbQ9yqPHDpD4gF8oUoQq7lUHfJqfmq1JvaJ1Nl6GSwhfJuXe9ZhoiRZjZT/XNl FSZvXaJ30IomziAbze4ISq44VJEGI3n3z8TtufXjhooz146ywDdt4NlgyIWn1nmq0cTR AHt6aoVBiINM7u1YWzLuPK5BkykVTbGAtc+UufoOizzKrvS04DBhRX2TkSyP9LJBXXo+ FnLD3wpa0iX+pN0EJExmm7wbULhiKVdQzrhCd0c0ohOjpIYWxdYdSplAlppmqZ2GNhAr etu7OlQF0/Y3/5dyJxLwtkoU/fWrNcQGvIrnhOIf9OStqSBWk8UGrfTJi5pR7s3mIWhX ju4w== X-Gm-Message-State: AOAM5330gIzmFY3bndZPv1IQnszwlEdOmoMsJIdMhvVLzGJT5YfDekLh POCE1Eit5CptBE9AnaZMrJ6SRHY3lnjWHw== X-Google-Smtp-Source: ABdhPJz+7wKN7U4Nvnf48xs5oUjdaYQW9x7RRYUtef7Jq22J4qXCKAKdut+44s98ErHVNNP01pWilA== X-Received: by 2002:a17:902:7689:: with SMTP id m9mr6024987pll.240.1598329216888; Mon, 24 Aug 2020 21:20:16 -0700 (PDT) Received: from localhost.localdomain ([122.167.211.143]) by smtp.gmail.com with ESMTPSA id 205sm13976667pfy.9.2020.08.24.21.20.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Aug 2020 21:20:15 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Tue, 25 Aug 2020 09:50:03 +0530 Message-Id: <20200825042007.18535-1-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [RFC PATCH v4 1/5] 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 Tue Aug 25 04:20:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21897 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 23B0444BC3D for ; Tue, 25 Aug 2020 07:20:31 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0A5DB68A8F8; Tue, 25 Aug 2020 07:20:31 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pj1-f68.google.com (mail-pj1-f68.google.com [209.85.216.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8E2A668798D for ; Tue, 25 Aug 2020 07:20:24 +0300 (EEST) Received: by mail-pj1-f68.google.com with SMTP id q93so226468pjq.0 for ; Mon, 24 Aug 2020 21:20:24 -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=M9bKMsTtsrzEUZ+RjIGR1GVnzPW6nS6oNGXnqmsj6/bKC3KstEuXaRiywCAJyG/zb7 uSKu3lkDXoxGGw0ld2uuvwkQxgUsO2df1i5NwJKOSuHZ2kgk9CH/ZVNSyWEGp59NIxLV b9Npm2M6t4JQMZMxBG1AFE6/gle8QdpGnFUGAXB0LuZhVdaxl1ZIN5KOFQElgFmwBOKs 3Si8GhHmnB3xPoVYMb3V4kBahai+bYRcY9eyQF+5KxX3JXuTP/Lq2WUipgT2GJNNNX1o jFnVJjMKeZx0CQ1F4H0zBYhl33dRA92BLxEmQV2X/2QPxkJVJggRrRHlPWGLH0s3Nr36 uzeg== 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=kF9mSMc8h96V54nnZWGHZciJomQ3HAXJAVBeIoHV95vA9dqav/fnhAXVbkABPdhceT X7Ml7fbNshPkSH175OxrnflgupGYEg8X4SmE3y3P345bdSMojR8Zr3i5ecbiMJfQaffz X7NFKaw+tVnCSyA62q6oIdTvP0ttR3vI6VXLK+9PYOo79Qi/g+/rHpahrbYDG7tbePBy jpSV9B7fL/frjX5H/+LJCkb6tbygz9UTF3NmKDDvlRUnuvR8+GHFFhDYXfCnWXE4zihS z1zFAeuQbxWE38hzhAmQkJPFgusbtFUbCuTll++sCokP6ckNGBOV6g3QU/MI4maRwr13 pwJw== X-Gm-Message-State: AOAM531rGpdvf6nyIS01HLBs8JPDryTIhc+hSTwunWsl4libUNjS3Dv+ TnPc0hHBuZuyaztg9uZRevlWsHWbPICfuw== X-Google-Smtp-Source: ABdhPJzS7UgNb8FJF4iOAFQgyl9hUP7jCKRYmY0CPKVx4nkBN0KKNHbjcj4Wd1bbGYaOanLxAWorcQ== X-Received: by 2002:a17:90b:256:: with SMTP id fz22mr34694pjb.105.1598329219772; Mon, 24 Aug 2020 21:20:19 -0700 (PDT) Received: from localhost.localdomain ([122.167.211.143]) by smtp.gmail.com with ESMTPSA id 205sm13976667pfy.9.2020.08.24.21.20.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Aug 2020 21:20:18 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Tue, 25 Aug 2020 09:50:04 +0530 Message-Id: <20200825042007.18535-2-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200825042007.18535-1-gautamramk@gmail.com> References: <20200825042007.18535-1-gautamramk@gmail.com> Subject: [FFmpeg-devel] [RFC PATCH v4 2/5] 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 Tue Aug 25 04:20:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21900 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 A61B144A14C for ; Tue, 25 Aug 2020 07:48:03 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8BBE1689AD1; Tue, 25 Aug 2020 07:48:03 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oi1-f193.google.com (mail-oi1-f193.google.com [209.85.167.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C6F6A687FA8 for ; Tue, 25 Aug 2020 07:47:56 +0300 (EEST) Received: by mail-oi1-f193.google.com with SMTP id z195so7466104oia.6 for ; Mon, 24 Aug 2020 21:47:56 -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=hKC6cJfg1r6uGA3Yl/Jz9RGe6Kxmz3lC+7QnNNMFrRA=; b=Hgv1IUSbEA0kWVYWT4ByehBNUQjW5HjPB7liR1M+UB+Fgm/MiCffHYFfgJkU4gpZ5H BayQXeCjyEDZIfeANT0xSrW1ZmkSRrcA+//SWJF9vVHspiWeX26znYcJNIHiOglPdO+U VWUluBvHN/TDYPGO1o/34+GXxX7irijf+Peg86eETwI9aLJOu2dJr4capyv5tBSSaIke t6LMFFoGhX/jYmBBRWXqIdpXTTKJGolfQFzZ480g2cu+mxH20SUsZMh9FNCsVArShYyD hpXHiP62vnc6itezOD554yiRpoeB0bXpdwx7TJK7H8oUiT98b3+bMiFipvefRuGwfMKR 5TkQ== 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=hKC6cJfg1r6uGA3Yl/Jz9RGe6Kxmz3lC+7QnNNMFrRA=; b=CZ1qtk8fnl1spv3Nk2RzA+sx4DNeMP7l3H7BbU1rBHKSYtvTOq+R2grlLLxuCzAjmL 2rOgesR5H/JrGRXpA1PNnBnTHYKoRIkPYkcytdwIGqFsjUcPB1/Q2xmQMWa5zkjEwWZZ SwkeWCNeuiNcFki5IMxFoxu45YQQIqLWnNikOY+EpETfuSnpc76V7N3ieY8eJJmBMhvz ukQEWgJE7Zlm/7LrhfPsroSaw8X4lIZJf9qXJnBrNDlOFE6E6YRkcvm5R1G+6PR/+1HR G6lAHkBGipQoApe0OtG6tkZ2n0pviyM2PN8jh9ZRW0zaFDiOSx8rjCT1EK40M4cjGfZU d86Q== X-Gm-Message-State: AOAM532xwOm/tpc8ZeBoO81zzu3WaZGOQwqP1bYXni/MgIerU5TN7Kr5 Wgf2auioyd4FQfoVbWoaTxRZiKG7Wf0jLw== X-Google-Smtp-Source: ABdhPJxrhGKx+g0SCPEU2MyxNGeNIZwmiVzO0NfDqZLcbOtJ35oRj5AeTP5/3sUHwC01taJQRmfPfg== X-Received: by 2002:a17:90a:4ec3:: with SMTP id v3mr63264pjl.72.1598329224287; Mon, 24 Aug 2020 21:20:24 -0700 (PDT) Received: from localhost.localdomain ([122.167.211.143]) by smtp.gmail.com with ESMTPSA id 205sm13976667pfy.9.2020.08.24.21.20.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Aug 2020 21:20:23 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Tue, 25 Aug 2020 09:50:05 +0530 Message-Id: <20200825042007.18535-3-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200825042007.18535-1-gautamramk@gmail.com> References: <20200825042007.18535-1-gautamramk@gmail.com> Subject: [FFmpeg-devel] [RFC PATCH v4 3/5] libavcodec/jpeg2000: Modify cleanup 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 ff_jpeg2000_cleanup function take in an extra parameter which indicates whether it is called from the encoder or decoder. --- libavcodec/j2kenc.c | 2 +- libavcodec/jpeg2000.c | 2 +- libavcodec/jpeg2000.h | 2 +- libavcodec/jpeg2000dec.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index 87acd2d5c9..711655f1d6 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -1220,7 +1220,7 @@ static void cleanup(Jpeg2000EncoderContext *s) for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ for (compno = 0; compno < s->ncomponents; compno++){ Jpeg2000Component *comp = s->tile[tileno].comp + compno; - ff_jpeg2000_cleanup(comp, codsty); + ff_jpeg2000_cleanup(comp, codsty, 1); } av_freep(&s->tile[tileno].comp); } diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index 3d3e7ec313..70c25a0ca2 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -580,7 +580,7 @@ void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty) } } -void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty) +void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty, int isencoder) { int reslevelno, bandno, precno; for (reslevelno = 0; diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index ad58b1ae88..fee9607e86 100644 --- a/libavcodec/jpeg2000.h +++ b/libavcodec/jpeg2000.h @@ -272,7 +272,7 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp, void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty); -void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty); +void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty, int isencoder); static inline int needs_termination(int style, int passno) { if (style & JPEG2000_CBLK_BYPASS) { diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 624542c2f8..c5192d007f 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -2123,7 +2123,7 @@ static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s) Jpeg2000Component *comp = s->tile[tileno].comp + compno; Jpeg2000CodingStyle *codsty = s->tile[tileno].codsty + compno; - ff_jpeg2000_cleanup(comp, codsty); + ff_jpeg2000_cleanup(comp, codsty, 0); } av_freep(&s->tile[tileno].comp); av_freep(&s->tile[tileno].packed_headers); From patchwork Tue Aug 25 04:20:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21898 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 11A4B44BC3D for ; Tue, 25 Aug 2020 07:20:37 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E66A668AA6E; Tue, 25 Aug 2020 07:20:36 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4E290688103 for ; Tue, 25 Aug 2020 07:20:29 +0300 (EEST) Received: by mail-pg1-f179.google.com with SMTP id g33so5914249pgb.4 for ; Mon, 24 Aug 2020 21:20:29 -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=shm8drhSPBteUHOlyKNpAXE5PGz8D9WerVyfK/t7c50=; b=lZ0NZcNbJb/bhHbv6m5nunlMHCWZ7ILh0rf7uDPnJFLXLeM/0Hz6MFECCasqEil3gQ Cbf0rDEo7hwsaJVF1ZPm6VpZ47Zo4oRhaIvAN8S33VBMlzhu+61ot1aSFlJWLkTFlk/b IC3Fh5qrkDBk4nCdOI8icIOZvx0KVZPC4rwVzQtW/7H0yDq54xpgV34sJs53IZKBDxwB Opobhk8mNESKZWQ1lGTuQsWKTKMgHnk/cysSDvHDKMUbA2sZSfGN4X6BbCNBTdiyagcA wOKrIJQ3D90Z6hhXXGk5uxZgq26iWZ2LhBVhe62hqiCd5vXe+eVrAsYzRamKZW9Ytdhn Bw1g== 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=shm8drhSPBteUHOlyKNpAXE5PGz8D9WerVyfK/t7c50=; b=X6At++1nS9vYPuglQoXwX5L5Ox5wm3lC9DUUCiBGkU1aOs2RSBuNE7++YuCBffQ9au S6xpY3YVQwZS3F8fokTWvn/X2gBCDhvp++/YTZjBk6p0ZNYi+uosSIxCyu0WzlAWEQFj PPETFH+sjm6tVRU18WbbrEoYFBBswTBd5VRTNrUtPFaj9wXP0+k/4xDhY0oIisLjgks4 v9qeNbheUd1Yrj7yTdSr3zRfNjs2tNleKwLFhDb3FOJVvoDhPliuwbjrmI2YR/4L6cHT jf7V3eERGrITJHBPrD29dQU4eT/XnjUGG7AKyXnQahAadu+3mbRaQ9iV1D1xl2arlQdx Jlow== X-Gm-Message-State: AOAM532NgUkssje8k6+MlicO1AZ2esRgYSDCnLzuG7q5nXKf0mnPIY1v +uFnWXSYwSH7vdV6ZOwH/aTucaCF1vxwlg== X-Google-Smtp-Source: ABdhPJzDgDqJsFbECH3etU7qmYc2z7V/YLqO03AcA8kAXqRN/2uvvIBiPNEpYcVah1QNq86ws8sMUQ== X-Received: by 2002:a62:f843:: with SMTP id c3mr6504600pfm.247.1598329226482; Mon, 24 Aug 2020 21:20:26 -0700 (PDT) Received: from localhost.localdomain ([122.167.211.143]) by smtp.gmail.com with ESMTPSA id 205sm13976667pfy.9.2020.08.24.21.20.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Aug 2020 21:20:25 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Tue, 25 Aug 2020 09:50:06 +0530 Message-Id: <20200825042007.18535-4-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200825042007.18535-1-gautamramk@gmail.com> References: <20200825042007.18535-1-gautamramk@gmail.com> Subject: [FFmpeg-devel] [RFC PATCH v4 4/5] 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. --- libavcodec/j2kenc.c | 492 +++++++++++++++++++---- libavcodec/jpeg2000.c | 13 +- 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 +- 11 files changed, 475 insertions(+), 102 deletions(-) diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index 711655f1d6..0e65adf445 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, 1); } 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 70c25a0ca2..1c294ad9e6 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,8 @@ void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty, i av_freep(&cblk->passes); av_freep(&cblk->lengthinc); av_freep(&cblk->data_start); + if (isencoder) + av_freep(&cblk->layers); } av_freep(&prec->cblk); } diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index fee9607e86..3c6e8ede16 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 Tue Aug 25 04:20:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21899 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 7F48644BDBB for ; Tue, 25 Aug 2020 07:47:26 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 56C26689C95; Tue, 25 Aug 2020 07:47:26 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oi1-f193.google.com (mail-oi1-f193.google.com [209.85.167.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7D777688058 for ; Tue, 25 Aug 2020 07:47:19 +0300 (EEST) Received: by mail-oi1-f193.google.com with SMTP id z195so7465183oia.6 for ; Mon, 24 Aug 2020 21:47:19 -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=3BttoGN+EBq4EHjjjcLReAGsqjWT3v4UEtigsFXf5/w=; b=iPs2u9S0Ig909lwP62MyrC7GZ9rhjl8YyPAX+faXHcbWVzbY1aE8gJppUZfVDy4zcs 2avFNK1qDWtcMINon1Cd0IEhKxbclgln1ibT6ARWVblHy5QXeORyprB4m3zZqjDs9wIe yppHy2l2aocoZg3M4HkYad/SYi5X+LKNlJXyEVsy9vbcFK31fQT/XdqVKkN3BIKxgFP4 Eez5JyLsh9qc06wSDIOYWzNSXM8HGQg8lRO3uaw9yhE/uB3Pv0hYz2Ur9Xp8zNjK/Sjd LlHP/QPS0zDoTruBOlw2U4yNFKEconnlIaK4JIi9KO0vydKuidjiWr1R4/peRhOwU873 UOBA== 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=3BttoGN+EBq4EHjjjcLReAGsqjWT3v4UEtigsFXf5/w=; b=m3tbXDzotx3Uxh5Fl/CRlWEOdH6jHoZRIjkC27I6NRka/0bRiiaAEDDxAAQmCfnH05 /idtmG6O557ozCkTWkQPG8I36p6NjRFHmimTGDVjb16RIeO/zADt0zIOV+3l+k00ZGDW S+JCDozPlOr7ZQyDmyKErxqA7AYaxCL/rK969DSilixIN6owHkEQE79MKBmbf7goCEF0 WE8ycPLJCBNLIxWWk+nDZsJ5KUznv6eB1J3kEISojUqfNlPId12pTWW7IBui4KAsQMnr VR7ALWuL38p/nhy8Ufoe3zBZHK87s7fEhyqZ0vR2kWOqm6b5qCgXKXxg6VE/zP3z5DQh GQCg== X-Gm-Message-State: AOAM530iGTV/04F06O0/lD9umFlheqEeN+kbCvWfcz1fRDhuKFoSQ3vv TqlBkTxvH4/xkHZLpIHWIYTDo/yZ8rkGQQ== X-Google-Smtp-Source: ABdhPJzMHEyAq3zLDAdUTbg/RYbcTAiJR0ubJfCaMjDT6jqsxXgi2GsLvgQGjwdbqm0x681Zf3UHrw== X-Received: by 2002:a17:90a:dc13:: with SMTP id i19mr28147pjv.161.1598329228385; Mon, 24 Aug 2020 21:20:28 -0700 (PDT) Received: from localhost.localdomain ([122.167.211.143]) by smtp.gmail.com with ESMTPSA id 205sm13976667pfy.9.2020.08.24.21.20.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Aug 2020 21:20:27 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Tue, 25 Aug 2020 09:50:07 +0530 Message-Id: <20200825042007.18535-5-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200825042007.18535-1-gautamramk@gmail.com> References: <20200825042007.18535-1-gautamramk@gmail.com> Subject: [FFmpeg-devel] [RFC PATCH v4 5/5] doc/encoders.texi: Add documentation for JPEG2000 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 adds documentation for the utility and usage of "layer_rates" option used in the JPEG2000 encoder. --- doc/encoders.texi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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