From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <ffmpeg-devel-bounces@ffmpeg.org> Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 29DFD4E9C5 for <ffmpegdev@gitmailbox.com>; Thu, 20 Mar 2025 01:20:04 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A08F5687B8C; Thu, 20 Mar 2025 03:19:30 +0200 (EET) Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 45939687B6B for <ffmpeg-devel@ffmpeg.org>; Thu, 20 Mar 2025 03:19:22 +0200 (EET) Received: by mail.gandi.net (Postfix) with ESMTPSA id 83C1D42DF9 for <ffmpeg-devel@ffmpeg.org>; Thu, 20 Mar 2025 01:19:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=niedermayer.cc; s=gm1; t=1742433561; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=awKfWcQppVnXm0cwtuKSssmoQ2vYWk9IPp45dFuQHeE=; b=FHHp2YL+XDLa7pgQncpf6mlrCEwHBIyfqj628HpEuQmV7n30GVxPKZtTsnXnicf8dsZjC2 KEu9OuxF/B+A/I5iaGg4+5oPbyhTijjCFIW5pgspUZDexF3gBe47WJwsnk3bLEOQuWRJ8M MJqYCiCBaUyqE+UK5IG0ajF0xAooPkC6tJKv5shnZFrp1uAfXaoK7uheLtIB9p/hO0DJ5s 8NLcZSFNuU5NQgzMnUMnNahE9aUWB6cvY24q2rBw6iLX0sLOv5YerGWjabewctJGLYHM/x MKgVYON8bik2k3nNewQ/8LuVWp+RPhJEcmWtlhmQv0ovstkcJhevCWhfR0r+fw== From: Michael Niedermayer <michael@niedermayer.cc> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Date: Thu, 20 Mar 2025 02:19:16 +0100 Message-ID: <20250320011916.2549051-4-michael@niedermayer.cc> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320011916.2549051-1-michael@niedermayer.cc> References: <20250320011916.2549051-1-michael@niedermayer.cc> MIME-Version: 1.0 X-GND-State: clean X-GND-Score: -70 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddugeeikeekucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenfghrlhcuvffnffculdeftddmnecujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefoihgthhgrvghlucfpihgvuggvrhhmrgihvghruceomhhitghhrggvlhesnhhivgguvghrmhgrhigvrhdrtggtqeenucggtffrrghtthgvrhhnpedvgfefudeijeetieejkefgfffhtdeludeuffdvfeelieevjeetvedufeetfeejfeenucfkphepgedurdeiiedrieejrdduudefnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepgedurdeiiedrieejrdduudefpdhhvghloheplhhotggrlhhhohhsthdpmhgrihhlfhhrohhmpehmihgthhgrvghlsehnihgvuggvrhhmrgihvghrrdgttgdpnhgspghrtghpthhtohepuddprhgtphhtthhopehffhhmphgvghdquggvvhgvlhesfhhfmhhpvghgrdhorhhg X-GND-Sasl: michael@niedermayer.cc Subject: [FFmpeg-devel] [PATCH 4/4] avcodec/ffv1: RC/RLE/LRU coder for remap table X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches <ffmpeg-devel.ffmpeg.org> List-Unsubscribe: <https://ffmpeg.org/mailman/options/ffmpeg-devel>, <mailto:ffmpeg-devel-request@ffmpeg.org?subject=unsubscribe> List-Archive: <https://ffmpeg.org/pipermail/ffmpeg-devel> List-Post: <mailto:ffmpeg-devel@ffmpeg.org> List-Help: <mailto:ffmpeg-devel-request@ffmpeg.org?subject=help> List-Subscribe: <https://ffmpeg.org/mailman/listinfo/ffmpeg-devel>, <mailto:ffmpeg-devel-request@ffmpeg.org?subject=subscribe> Reply-To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" <ffmpeg-devel-bounces@ffmpeg.org> Archived-At: <https://master.gitmailbox.com/ffmpegdev/20250320011916.2549051-4-michael@niedermayer.cc/> List-Archive: <https://master.gitmailbox.com/ffmpegdev/> List-Post: <mailto:ffmpegdev@gitmailbox.com> 8% overall compression gain for 32bit float data which originates from 16bit floats Sponsored-by: Sovereign Tech Fund Signed-off-by: Michael Niedermayer <michael@niedermayer.cc> --- libavcodec/ffv1.h | 2 ++ libavcodec/ffv1dec.c | 22 +++++++++++++- libavcodec/ffv1enc.c | 70 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h index d19c8e3ed42..64be996322c 100644 --- a/libavcodec/ffv1.h +++ b/libavcodec/ffv1.h @@ -54,6 +54,8 @@ #define AC_RANGE_CUSTOM_TAB 2 #define AC_RANGE_DEFAULT_TAB_FORCE -2 +#define NLRU 33 + typedef struct VlcState { uint32_t error_sum; int16_t drift; diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index d45aabbbde8..c758040e1a8 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -242,7 +242,7 @@ static int decode_slice_header(const FFV1Context *f, } if (f->combined_version >= 0x40004) { sc->remap = ff_ffv1_get_symbol(c, state, 0); - if (sc->remap > 2U || + if (sc->remap > 3U || sc->remap && !f->flt) { av_log(f->avctx, AV_LOG_ERROR, "unsupported remap %d\n", sc->remap); return AVERROR_INVALIDDATA; @@ -285,12 +285,30 @@ static int decode_remap(FFV1Context *f, FFV1SliceContext *sc) int lu = 0; uint8_t state[2][32]; int64_t i; + int lru[NLRU]; memset(state, 128, sizeof(state)); + + for(int i = 0; i<NLRU; i++) + lru[i] = i; + for (i=0; i <= end ; i++) { unsigned run = get_symbol_inline(&sc->c, state[lu], 0); + if (sc->remap == 3 && !lu) { + if (run < NLRU) { + unsigned v = lru[run]; + memmove(lru+1, lru, sizeof(int)*run); + run = v; + } else { + memmove(lru+1, lru, sizeof(int)*(NLRU-1)); + run -= NLRU; + } + lru[0] = run; + } if (run > end - i + 1) return AVERROR_INVALIDDATA; if (lu) { + if (run > 65536 - j) + return AVERROR_INVALIDDATA; lu ^= !run; while (run--) { if (end == 0xFFFF) { @@ -305,6 +323,8 @@ static int decode_remap(FFV1Context *f, FFV1SliceContext *sc) if (end == 0xFFFF) { sc->fltmap [p][j++] = i ^ ((i& 0x8000) ? 0 : flip); } else { + if (j > 65535) + return AVERROR_INVALIDDATA; sc->fltmap32[p][j++] = i ^ ((i&0x80000000) ? 0 : flip); } } diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 12f3952453b..5b4556e63dd 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -949,7 +949,7 @@ av_cold int ff_ffv1_encode_setup_plane_info(AVCodecContext *avctx, av_assert0(s->bits_per_raw_sample >= 8); if (s->remap_mode < 0) - s->remap_mode = s->flt ? 2 : 0; + s->remap_mode = s->flt ? (s->bits_per_raw_sample == 32 ? 3 : 2) : 0; if (s->remap_mode == 0 && s->bits_per_raw_sample == 32) { av_log(avctx, AV_LOG_ERROR, "32bit requires remap\n"); return AVERROR(EINVAL); @@ -1179,24 +1179,53 @@ static void encode_histogram_remap(FFV1Context *f, FFV1SliceContext *sc) int lu = 0; uint8_t state[2][32]; int run = 0; + + int lru[NLRU]; + + for(int i = 0; i<NLRU; i++) + lru[i] = i; + memset(state, 128, sizeof(state)); - for (int i= 0; i<65536; i++) { + for (int i= 0; i<=65536; i++) { int ri = i ^ ((i&0x8000) ? 0 : flip); - int u = sc->fltmap[p][ri]; - sc->fltmap[p][ri] = j; + int u; + if (i < 65536) { + u = sc->fltmap[p][ri]; + sc->fltmap[p][ri] = j; + } else { + if (!run) + break; + u = !lu; + } j+= u; if (lu == u) { run ++; } else { - put_symbol_inline(&sc->c, state[lu], run, 0, NULL, NULL); + unsigned v = run; + if (sc->remap == 3 && !lu) { + int r; + for(r = 0; r < NLRU; r++) { + if (v == lru[r]) { + memmove(lru+1, lru, sizeof(int)*r); + lru[0] = v; + v = r; + break; + } + } + if (r == NLRU) { + memmove(lru+1, lru, sizeof(int)*(NLRU-1)); + lru[0] = v; + v += NLRU; + } + //TODO escape handling + } + put_symbol_inline(&sc->c, state[lu], v, 0, NULL, NULL); if (run == 0) lu = u; run = 0; } } - if (run) - put_symbol(&sc->c, state[lu], run, 0); } } @@ -1271,6 +1300,10 @@ static void encode_float32_remap(FFV1Context *f, FFV1SliceContext *sc, int run = 0; int64_t last_val = -1; int compact_index = -1; + int lru[NLRU]; + + for(int i = 0; i<NLRU; i++) + lru[i] = i; memset(state, 128, sizeof(state)); for (int i= 0; i<pixel_num+1; i++) { @@ -1300,8 +1333,25 @@ static void encode_float32_remap(FFV1Context *f, FFV1SliceContext *sc, continue; } } else { + int v = val - last_val - 1; av_assert2(run == 0); - put_symbol_inline(&sc->c, state[lu], val - last_val - 1, 0, NULL, NULL); + if (sc->remap == 3) { + int r; + for(r = 0; r < NLRU; r++) { + if (v == lru[r]) { + memmove(lru+1, lru, sizeof(int)*r); + lru[0] = v; + v = r; + break; + } + } + if (r == NLRU) { + memmove(lru+1, lru, sizeof(int)*(NLRU-1)); + lru[0] = v; + v += NLRU; + } + } + put_symbol_inline(&sc->c, state[lu], v, 0, NULL, NULL); if (val - last_val == 1) lu ^= 1; last_val = val; @@ -1706,7 +1756,7 @@ static const AVOption options[] = { { .i64 = QTABLE_GT8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" }, { "rawlsb", "number of LSBs stored RAW", OFFSET(rawlsb), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8, VE }, - { "remap_mode", "Remap Mode", OFFSET(remap_mode), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 2, VE, .unit = "remap_mode" }, + { "remap_mode", "Remap Mode", OFFSET(remap_mode), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 3, VE, .unit = "remap_mode" }, { "auto", "Automatic", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" }, { "off", "Disabled", 0, AV_OPT_TYPE_CONST, @@ -1715,6 +1765,8 @@ static const AVOption options[] = { { .i64 = 1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" }, { "flipdualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" }, + { "rlelru", "RLE/LRU", 0, AV_OPT_TYPE_CONST, + { .i64 = 3 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" }, { NULL } -- 2.48.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".