ffmpeg-devel
Threads by month
- ----- 2026 -----
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
August 2026
- 19 participants
- 91 discussions
Hi,
What does the https://ffmpeg.org/releases/ffmpeg-9.0.tar.xz tarball exactly correspond to? It's not the n9.0 tag, at least.
From what I can determine, it contains n9.0~59, minus .gitignore files. Is that how the release tarball is supposed to be composed?
-Dimitry
2
1
pcm_dvda: sample + findings for "Mixed group sample rates (96000, 48000) is not implemented"
by Jeffrey A. Wormsley 10 Aug '26
by Jeffrey A. Wormsley 10 Aug '26
10 Aug '26
--- Preamble ---
The technical analysis below was generated by Claude (Anthropic's AI
assistant), working from raw disc data I provided over an extended
back-and-forth investigation. I'm including it as-is since I believe
the findings are sound and independently verified against a
known-correct reference decode, but I want to be upfront that an AI,
not me, did the reverse-engineering. My own note follows at the end.
--- Start of AI Generated Analysis ---
Hi,
pcm_dvda correctly identifies this DVD-Audio disc as using split channel
groups at different sample rates, and correctly declines to guess at a
decode rather than produce wrong output:
[pcm_dvda] Mixed group sample rates (96000, 48000) is not implemented.
I've spent a while reverse-engineering this specific disc against a
known-correct reference decode (foobar2000, via its DVDADecoder plugin,
which does handle this case) and have a reasonably complete picture of
the container-level structure, but not the intra-frame sample layout.
Sharing what's confirmed in case it's useful, and asking whether the
project has (or would want) a sample of this format.
Disc: commercial DVD-Audio release, authored with Cirlinca HD-Audio Solo
Ultra (confirmed via the UDF ImplementationId field, "*CLN::DOS"). Happy
to upload the ISO or just the relevant AOB file(s) to
streams.videolan.org if useful - it's ~2.7GB total, or I can extract a
smaller isolated sample if that's more practical.
## What's confirmed
All of the below was verified against the disc's own declared fields
(not assumed), and cross-checked against a byte-perfect reference decode
(foobar2000) sample-for-sample, not by correlation/similarity.
- LPCM substream header (private_stream_1, substream_id 0xA0) declares:
- sample_size byte 0x22: both nibbles = 2 -> 24-bit for both groups
(per the documented 0=16bit/1=20bit/2=24bit scale)
- sample_rate byte 0x10: high nibble 1 = 96kHz (group 1), low nibble 0
= 48kHz (group 2)
- channel_group_assignment = 12 (decimal) -> L, R, C, LFE, Ls, Rs, per
the documented assignment table - confirmed against what a reference
decode shows in Audacity (Left Front, Right Front, Center, LFE, Left
Rear, Right Rear, in that order)
- header_length (substream offset +2..+3) is a genuine 2-byte field, not
a single byte - the high byte is 0 on every pack on this disc, so a
1-byte read happens to give the same numeric result here, but isn't
correct in general.
- byte_pointer (substream offset +4..+5) is a genuine 2-byte field
giving the offset, within this pack's audio payload, of the first
frame-aligned byte - i.e. how many bytes of this pack's payload belong
to completing a frame that started in the previous pack. Confirmed to
be 1-indexed (points to "the Nth byte", not a 0-indexed offset) -
determined empirically by finding the byte count that makes every
subsequent pack's declared byte_pointer match a predicted value
exactly.
- Frame size is exactly 960 bytes: 480 bytes for the two 96kHz channels
+ 480 bytes for the four 48kHz channels, both at 24-bit
(2*96000*3 + 4*48000*3, over the frame's common 80/40-sample time
window). This isn't inferred from the byte-rate alone - it's proven
arithmetically: byte_pointer decrements by exactly 48 (= 1968 mod 960,
where 1968 is this disc's typical per-pack audio payload size) on
every single one of 10,740 consecutive packs across the first track,
zero exceptions, including correct wraparound at the 960-byte
boundary. A 27-byte or 20-byte frame (both considered and ruled out
below) would predict a different, and wrong, decrement.
- The two 96kHz channels are channels 1 and 2 in the
channel_group_assignment
order (i.e. the first two channels declared, matching L/R) - confirmed
via the disc's own measured total byte rate matching a 2ch@96kHz +
4ch@48kHz split, not the reverse.
## What's not resolved: the intra-frame sample layout
Given the above, each 960-byte frame is known to split into a 480-byte
half for the two 96kHz channels (80 samples/channel) and a 480-byte half
for the four 48kHz channels (40 samples/channel), in one order or the
other. What hasn't been determined is how samples are packed to bytes
within each half.
Tested, all via exact sample-for-sample comparison against the
reference decode (not correlation or partial matching), on the first
sector of the first track - chosen specifically because the disc's true
start guarantees an unambiguous WAV-sample alignment with no
accumulated/derived offset in the way:
1. Four named byte layouts within the confirmed 480+480 structure, each
an extension of the "MSB+mid pairs, then all LSBs" style already
verified correct for this format's ordinary (non-split-group,
single-rate) LPCM case:
- channel-interleaved pairs, LSBs deferred to end of group
- channel-blocked pairs, LSBs deferred to end of group
- fully planar, channel-interleaved (all MSBs, then all mids, then
all LSBs)
- fully planar, channel-blocked
Each tested with both possible group orderings (96kHz half first or
48kHz half first) - 8 total combinations. All fail at or within the
first few samples on every channel.
2. A separate structural hypothesis (3 channels @ 96kHz + 3 channels @
48kHz rather than 2+4, in 27-byte blocks, straight big-endian 3-byte
samples, no bit/nibble splitting) - considered because it's what a
second LLM proposed when given the same raw bytes; testing it
directly seemed more useful than debating it. It also fails
immediately - and is independently inconsistent with the disc's own
byte_pointer arithmetic above, which requires a 960-byte frame, not
27.
Happy to share the small validator tool (a self-contained C# console
app) that produced these results if it's useful for reproducing them,
along with the specific sector 0 byte dump and the matching reference
WAV excerpt.
## Ask
Is there a documented (or tribal-knowledge) description of the
intra-frame byte layout for split sample-rate/bit-depth LPCM groups on
DVD-Audio? Everything above was derived from the disc's own declared
header fields plus exhaustive testing against a reference decode; the
one piece we don't have is an authoritative description of the sample
packing itself, which is presumably needed to implement this in
pcm_dvda. Happy to help test against additional discs/samples if that's
useful.
--- End of AI Generated Analysis ---
I have been attempting to use AI tools to decode DVD ISOs to extract all audio
(no video) data, and have successfully managed to get it to decode most of
the ISO files I have thrown at it, including most DVDA and DVDV files.
Originally,
this was done by simple scripting, calling command line utilities such as
ffmpeg to do the actual extraction. However, I have one ISO (so far) with
mixed audio rates that so far has defied extraction with any command line
tool I have pointed at it. The data extracted so far has at best been static
with the actual audio somewhat discernable beneath the static.
I make no claim to understand the data format beyond what I have read on
various web pages, hence asking AI to help with this. The project started
out as a simple script to detect the ISO format then call the proper
command line tool to extract the audio, originally only ffmpeg, later also
attempting to use dvda-author and a few others. This is when I found no
tool quite handles all formats properly, and got into trying extracting the
PCM data from the VOB files directly using the C# compiler that comes with
Windows (MLP data is still extracted via ffmpeg), and this led to the
discovery that the 96Khs/48Khz mixed format isn't really handled by any
command line tool. The AI tool works well for pretty much everything else
I have tried but this. Of all of the other tools I have tried, only
foobar2000 with the dvda decoder works, others produce either silence (VLC,
31 hours of
it), or the same sort of static with underlying audio (Lossless Extract),
or crashes (dvda-author).
I don't know if the output of this AI will prove useful in any way, but if
so, I offer the information to you. If not, or it is not the sort of thing
you want to make use of for philosophical reasons (totally understandable),
then I can at least provide any data samples that you may need.
Thanks,
Jeff Wormsley
1
0
[PR] fixup: resolve trailing whitespace and fate-source errors from #23795 (PR #24068)
by Jia.Yuan 10 Aug '26
by Jia.Yuan 10 Aug '26
10 Aug '26
PR #24068 opened by Jia.Yuan
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24068
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24068.patch
This PR resolves the Pre-commit and FATE-source CI failures from the original "RISC-V: optimize fdct" merge (#23795). The missing commit has been recovered and applied on top of the latest master branch.
No functional changes, just CI and formatting fixes.
From 12b78a75e29e505f75693e14d3c913b866aa4159 Mon Sep 17 00:00:00 2001
From: yuanjia <yuan.jia(a)sanechips.com.cn>
Date: Mon, 13 Jul 2026 16:51:35 +0800
Subject: [PATCH 1/2] RISC-V: optimize fdct
---
libavcodec/avcodec.h | 1 +
libavcodec/fdctdsp.c | 2 +
libavcodec/fdctdsp.h | 2 +
libavcodec/options_table.h | 1 +
libavcodec/riscv/Makefile | 2 +
libavcodec/riscv/fdct.h | 26 ++++
libavcodec/riscv/fdctdsp_init.c | 45 ++++++
libavcodec/riscv/fdctdsp_rvv.S | 254 ++++++++++++++++++++++++++++++++
libavcodec/riscv/rvv.S | 85 +++++++++++
libavcodec/tests/riscv/dct.c | 30 ++++
10 files changed, 448 insertions(+)
create mode 100644 libavcodec/riscv/fdct.h
create mode 100644 libavcodec/riscv/fdctdsp_init.c
create mode 100644 libavcodec/riscv/fdctdsp_rvv.S
create mode 100644 libavcodec/riscv/rvv.S
create mode 100644 libavcodec/tests/riscv/dct.c
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 6bce0d388d..475b3bcb74 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1535,6 +1535,7 @@ typedef struct AVCodecContext {
#define FF_DCT_ALTIVEC 5
#define FF_DCT_FAAN 6
#define FF_DCT_NEON 7
+#define FF_DCT_RVV 8
/**
* IDCT algorithm, see FF_IDCT_* below.
diff --git a/libavcodec/fdctdsp.c b/libavcodec/fdctdsp.c
index d20558ce88..2d217ae664 100644
--- a/libavcodec/fdctdsp.c
+++ b/libavcodec/fdctdsp.c
@@ -48,5 +48,7 @@ av_cold void ff_fdctdsp_init(FDCTDSPContext *c, AVCodecContext *avctx)
ff_fdctdsp_init_ppc(c, avctx, high_bit_depth);
#elif ARCH_X86
ff_fdctdsp_init_x86(c, avctx, high_bit_depth);
+#elif ARCH_RISCV
+ ff_fdctdsp_init_riscv(c, avctx, high_bit_depth);
#endif
}
diff --git a/libavcodec/fdctdsp.h b/libavcodec/fdctdsp.h
index cad99ed7ca..6399f49192 100644
--- a/libavcodec/fdctdsp.h
+++ b/libavcodec/fdctdsp.h
@@ -38,6 +38,8 @@ void ff_fdctdsp_init_ppc(FDCTDSPContext *c, struct AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_fdctdsp_init_x86(FDCTDSPContext *c, struct AVCodecContext *avctx,
unsigned high_bit_depth);
+void ff_fdctdsp_init_riscv(FDCTDSPContext *c, struct AVCodecContext *avctx,
+ unsigned high_bit_depth);
void ff_fdct_ifast(int16_t *data);
void ff_fdct_ifast248(int16_t *data);
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index a16fc84df4..7838f31972 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -158,6 +158,7 @@ static const AVOption avcodec_options[] = {
{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
{"faan", "floating point AAN DCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
{"neon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_NEON }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
+{ "rvv", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_DCT_RVV }, INT_MIN, INT_MAX, V|E, .unit = "dct" },
{"lumi_mask", "compresses bright areas stronger than medium ones", OFFSET(lumi_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
{"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
{"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
diff --git a/libavcodec/riscv/Makefile b/libavcodec/riscv/Makefile
index 28d745cfe3..ad48b65ee8 100644
--- a/libavcodec/riscv/Makefile
+++ b/libavcodec/riscv/Makefile
@@ -6,6 +6,8 @@ OBJS-$(CONFIG_AC3DSP) += riscv/ac3dsp_init.o
RV-OBJS-$(CONFIG_AC3DSP) += riscv/ac3dsp_rvb.o
RVV-OBJS-$(CONFIG_AC3DSP) += riscv/ac3dsp_rvv.o
RVVB-OBJS-$(CONFIG_AC3DSP) += riscv/ac3dsp_rvvb.o
+OBJS-$(CONFIG_FDCTDSP) += riscv/fdctdsp_init.o
+RVV-OBJS-$(CONFIG_FDCTDSP) += riscv/fdctdsp_rvv.o
OBJS-$(CONFIG_ALAC_DECODER) += riscv/alacdsp_init.o
RVV-OBJS-$(CONFIG_ALAC_DECODER) += riscv/alacdsp_rvv.o
OBJS-$(CONFIG_AUDIODSP) += riscv/audiodsp_init.o
diff --git a/libavcodec/riscv/fdct.h b/libavcodec/riscv/fdct.h
new file mode 100644
index 0000000000..ab88634b73
--- /dev/null
+++ b/libavcodec/riscv/fdct.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_RVV_FDCT_H
+#define AVCODEC_RVV_FDCT_H
+
+#include <stdint.h>
+
+void ff_fdct_rvv(int16_t *block);
+
+#endif /* AVCODEC_RVV_FDCT_H */
diff --git a/libavcodec/riscv/fdctdsp_init.c b/libavcodec/riscv/fdctdsp_init.c
new file mode 100644
index 0000000000..0429b8d04d
--- /dev/null
+++ b/libavcodec/riscv/fdctdsp_init.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2026 Jia Yuan <yuan.jia(a)sanechips.com.cn>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/riscv/cpu.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/fdctdsp.h"
+#include "fdct.h"
+
+av_cold void ff_fdctdsp_init_riscv(FDCTDSPContext *c, AVCodecContext *avctx,
+ unsigned high_bit_depth)
+{
+#if HAVE_RVV
+ int cpu_flags = av_get_cpu_flags();
+ if (!(cpu_flags & AV_CPU_FLAG_RVV_I32) || !ff_rv_vlen_least(128)) {
+ return;
+ }
+
+ const int dct_algo = avctx->dct_algo;
+
+ if (!high_bit_depth) {
+ if (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_RVV) {
+ c->fdct = ff_fdct_rvv;
+ }
+ }
+#endif
+}
diff --git a/libavcodec/riscv/fdctdsp_rvv.S b/libavcodec/riscv/fdctdsp_rvv.S
new file mode 100644
index 0000000000..9906c2c5d2
--- /dev/null
+++ b/libavcodec/riscv/fdctdsp_rvv.S
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2026 Jia Yuan <yuan.jia(a)sanechips.com.cn>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/riscv/asm.S"
+#include "rvv.S"
+
+/* Constants for FDCT */
+#define CONST_BITS 13
+#ifndef EIGHT_BIT_SAMPLES
+# define PASS1_BITS 1
+#else
+# define PASS1_BITS 2
+#endif
+#define DESCALE_P1 (CONST_BITS - PASS1_BITS) /* 12 or 11 */
+#define DESCALE_P2 (CONST_BITS + PASS1_BITS) /* 14 or 15 */
+
+/* FIX(x) = (int)( (x) * (1 << CONST_BITS) + 0.5 ) */
+#define F_0_298 2446
+#define F_0_390 3196
+#define F_0_541 4433
+#define F_0_765 6270
+#define F_0_899 7373
+#define F_1_175 9633
+#define F_1_501 12299
+#define F_1_847 15137
+#define F_1_961 16069
+#define F_2_053 16819
+#define F_2_562 20995
+#define F_3_072 25172
+
+/* RVV constant table (aligned on 4 bytes) */
+ .balign 4
+fdct_consts:
+ .hword F_0_298, -F_0_390, F_0_541, F_0_765
+ .hword -F_0_899, F_1_175, F_1_501, -F_1_847
+ .hword -F_1_961, F_2_053, -F_2_562, F_3_072
+ .hword 0, 0, 0, 0 /* padding */
+
+/* ------------------------------------------------------- */
+/* One‑dimensional FDCT (8 elements in, 8 elements out) */
+/* pass: 0 = first pass (shift DESCALE_P1, shl out0/out4)*/
+/* 1 = second pass (shift DESCALE_P2, srshr out0/4)*/
+/* ------------------------------------------------------- */
+.macro fdct_1d pass, r0, r1, r2, r3, r4, r5, r6, r7
+ /* Input : r0..r7 (int16, m1) */
+ /* During 32‑bit arithmetic we switch to e32, m2 */
+ /* Output : v16..v23 (int16, m1) */
+
+ /* ---- Butterfly sums/differences (16‑bit) ---- */
+ vadd.vv v24, \r0, \r7 /* tmp0 = S0 + S7 */
+ vsub.vv v31, \r0, \r7 /* tmp7 = S0 - S7 */
+ vadd.vv v25, \r1, \r6 /* tmp1 = S1 + S6 */
+ vsub.vv v30, \r1, \r6 /* tmp6 = S1 - S6 */
+ vadd.vv v26, \r2, \r5 /* tmp2 = S2 + S5 */
+ vsub.vv v29, \r2, \r5 /* tmp5 = S2 - S5 */
+ vadd.vv v27, \r3, \r4 /* tmp3 = S3 + S4 */
+ vsub.vv v28, \r3, \r4 /* tmp4 = S3 - S4 */
+
+ /* ---- Even part ---- */
+ vadd.vv v4, v24, v27 /* tmp10 = tmp0 + tmp3 */
+ vsub.vv v5, v24, v27 /* tmp13 = tmp0 - tmp3 */
+ vadd.vv v6, v25, v26 /* tmp11 = tmp1 + tmp2 */
+ vsub.vv v7, v25, v26 /* tmp12 = tmp1 - tmp2 */
+
+ vadd.vv v16, v4, v6 /* out0 = tmp10 + tmp11 */
+ vsub.vv v20, v4, v6 /* out4 = tmp10 - tmp11 */
+ vadd.vv v12, v7, v5 /* (tmp12 + tmp13) for z1 */
+
+ /* For the first pass: left shift out0 and out4 */
+.if \pass == 0
+ vsll.vi v16, v16, PASS1_BITS
+ vsll.vi v20, v20, PASS1_BITS
+.else
+ /* Second pass: rounding right shift out0 and out4 */
+ vsetivli zero, 8, e32, m2, ta, ma
+ vsext.vf2 v8, v16
+ vsext.vf2 v10, v20
+ vsetivli zero, 8, e16, m1, ta, ma
+ vnclip.wi v16, v8, PASS1_BITS
+ vnclip.wi v20, v10, PASS1_BITS
+.endif
+
+ li t2, F_0_541
+ li t3, F_0_765
+ li t4, -(F_1_847)
+
+ /* z1 = (tmp12+tmp13) * F_0_541 */
+ vwmul.vx v18, v12, t2
+ vsetivli zero, 8, e32, m2, ta, ma
+ vmv.v.v v22, v18 /* copy for out6 */
+
+ /* out2 = z1 + tmp13 * F_0_765 */
+ vsetivli zero, 8, e16, m1, ta, ma
+ vwmacc.vx v18, t3, v5
+
+ /* out6 = z1 + tmp12 * (-F_1_847) */
+ vwmacc.vx v22, t4, v7
+
+ /* Narrow & shift (DESCALE_P1 or DESCALE_P2) */
+ vsetivli zero, 8, e16, m1, ta, ma
+.if \pass == 0
+ vnclip.wi v18, v18, DESCALE_P1
+ vnclip.wi v22, v22, DESCALE_P1
+.else
+ vnclip.wi v18, v18, DESCALE_P2
+ vnclip.wi v22, v22, DESCALE_P2
+.endif
+
+ /* ---- Odd part ---- */
+ vadd.vv v2, v28, v31 /* z1 */
+ vadd.vv v3, v29, v30 /* z2 */
+ vadd.vv v6, v28, v30 /* z3 */
+ vadd.vv v7, v29, v31 /* z4 */
+
+ /* z5 = (z3 + z4) * F_1_175 */
+ li t2, F_1_175
+ vwmul.vx v4, v6, t2 /* z5 = z3 * F_1_175 */
+ vwmacc.vx v4, t2, v7 /* z5 += z4 * F_1_175 */
+
+ /* tmp4 = S4 * F_0_298, tmp5 = S5 * F_2_053,
+ tmp6 = S6 * F_3_072, tmp7 = S7 * F_1_501 */
+ li t3, F_0_298
+ li t4, F_2_053
+ li t5, F_3_072
+ li t6, F_1_501
+ vwmul.vx v8, v28, t3
+ vwmul.vx v10, v29, t4
+ vwmul.vx v12, v30, t5
+ vwmul.vx v14, v31, t6
+
+ /* z1..z4 with negative coefficients */
+ li t1, -(F_0_899)
+ li t2, -(F_2_562)
+ li t3, -(F_1_961)
+ li t4, -(F_0_390)
+ vwmul.vx v24, v2, t1
+ vwmul.vx v26, v3, t2
+ vwmul.vx v28, v6, t3
+ vwmul.vx v30, v7, t4
+
+ vsetivli zero, 8, e32, m2, ta, ma
+ /* z3 += z5, z4 += z5 */
+ vadd.vv v28, v28, v4
+ vadd.vv v30, v30, v4
+
+ /* tmp4 += z1 ; tmp5 += z2 ; tmp6 += z3 ; tmp7 += z4 */
+ vadd.vv v8, v8, v24 /* tmp4 += z1 */
+ vadd.vv v10, v10, v26 /* tmp5 += z2 */
+ vadd.vv v12, v12, v28 /* tmp6 += z3 */
+ vadd.vv v14, v14, v30 /* tmp7 += z4 */
+
+ /* tmp4 += z3 ; tmp5 += z4 ; tmp6 += z2 ; tmp7 += z1 */
+ vadd.vv v8, v8, v28 /* tmp4 += z3 */
+ vadd.vv v10, v10, v30 /* tmp5 += z4 */
+ vadd.vv v12, v12, v26 /* tmp6 += z2 */
+ vadd.vv v14, v14, v24 /* tmp7 += z1 */
+
+ /* ---- Restore 16‑bit mode ---- */
+ vsetivli zero, 8, e16, m1, ta, ma
+.if \pass == 0
+ vnclip.wi v23, v8, DESCALE_P1
+ vnclip.wi v21, v10, DESCALE_P1
+ vnclip.wi v19, v12, DESCALE_P1
+ vnclip.wi v17, v14, DESCALE_P1
+.else
+ vnclip.wi v23, v8, DESCALE_P2
+ vnclip.wi v21, v10, DESCALE_P2
+ vnclip.wi v19, v12, DESCALE_P2
+ vnclip.wi v17, v14, DESCALE_P2
+.endif
+
+.endm
+
+/* ------------------------------------------------------- */
+/* 8×8 FDCT entry point */
+/* void ff_fdct_rvv(int16_t *data) */
+/* ------------------------------------------------------- */
+func ff_fdct_rvv, zve32x
+ lpad 0
+
+ li t1, 0x55
+ vsetivli zero, 8, e16, m1, ta, ma
+ vmv.v.x v0, t1
+ csrwi vxrm, 0
+
+ /* Load 8×8 block (rows) */
+ mv t0, a0
+ vle16.v v16, (t0)
+ addi t0, t0, 16
+ vle16.v v17, (t0)
+ addi t0, t0, 16
+ vle16.v v18, (t0)
+ addi t0, t0, 16
+ vle16.v v19, (t0)
+ addi t0, t0, 16
+ vle16.v v20, (t0)
+ addi t0, t0, 16
+ vle16.v v21, (t0)
+ addi t0, t0, 16
+ vle16.v v22, (t0)
+ addi t0, t0, 16
+ vle16.v v23, (t0)
+
+ /* First transpose: rows → columns */
+ TRANSPOSE_8x8 16, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23
+
+ /* First 1‑D FDCT (columns) */
+ vsetivli zero, 8, e16, m1, ta, ma
+ fdct_1d 0, v8, v9, v10, v11, v12, v13, v14, v15
+
+ /* Transpose again: columns → rows */
+ TRANSPOSE_8x8 16, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23
+
+ /* Second 1‑D FDCT (rows) */
+ vsetivli zero, 8, e16, m1, ta, ma
+ fdct_1d 1, v8, v9, v10, v11, v12, v13, v14, v15
+
+ /* Store the final 8×8 block back to memory */
+ mv t0, a0
+ vse16.v v16, (t0)
+ addi t0, t0, 16
+ vse16.v v17, (t0)
+ addi t0, t0, 16
+ vse16.v v18, (t0)
+ addi t0, t0, 16
+ vse16.v v19, (t0)
+ addi t0, t0, 16
+ vse16.v v20, (t0)
+ addi t0, t0, 16
+ vse16.v v21, (t0)
+ addi t0, t0, 16
+ vse16.v v22, (t0)
+ addi t0, t0, 16
+ vse16.v v23, (t0)
+
+ ret
+endfunc
\ No newline at end of file
diff --git a/libavcodec/riscv/rvv.S b/libavcodec/riscv/rvv.S
new file mode 100644
index 0000000000..338929b76c
--- /dev/null
+++ b/libavcodec/riscv/rvv.S
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2026 Jia Yuan <yuan.jia(a)sanechips.com.cn>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+// v0 must be 0x55 as mask
+.macro TRANSPOSE_8x8 es, d0, d1, d2, d3, d4, d5, d6, d7, r0, r1, r2, r3, r4, r5, r6, r7
+ vslideup.vi \d0, \r1, 1
+ vslidedown.vi \d1, \r0, 1
+ vslideup.vi \d2, \r3, 1
+ vslidedown.vi \d3, \r2, 1
+ vslideup.vi \d4, \r5, 1
+ vslidedown.vi \d5, \r4, 1
+ vslideup.vi \d6, \r7, 1
+ vslidedown.vi \d7, \r6, 1
+ vmerge.vvm \d0, \d0, \r0, v0
+ vmerge.vvm \d1, \r1, \d1, v0
+ vmerge.vvm \d2, \d2, \r2, v0
+ vmerge.vvm \d3, \r3, \d3, v0
+ vmerge.vvm \d4, \d4, \r4, v0
+ vmerge.vvm \d5, \r5, \d5, v0
+ vmerge.vvm \d6, \d6, \r6, v0
+ vmerge.vvm \d7, \r7, \d7, v0
+
+.if \es == 16
+ vsetivli zero, 4, e32, m1, ta, ma
+.elseif \es == 8
+ vsetivli zero, 4, e16, m1, ta, ma
+.endif
+
+ vslideup.vi \r0, \d2, 1
+ vslidedown.vi \r1, \d0, 1
+ vslideup.vi \r2, \d3, 1
+ vslidedown.vi \r3, \d1, 1
+ vslideup.vi \r4, \d6, 1
+ vslidedown.vi \r5, \d4, 1
+ vslideup.vi \r6, \d7, 1
+ vslidedown.vi \r7, \d5, 1
+ vmerge.vvm \r0, \r0, \d0, v0
+ vmerge.vvm \r1, \d2, \r1, v0
+ vmerge.vvm \r2, \r2, \d1, v0
+ vmerge.vvm \r3, \d3, \r3, v0
+ vmerge.vvm \r4, \r4, \d4, v0
+ vmerge.vvm \r5, \d6, \r5, v0
+ vmerge.vvm \r6, \r6, \d5, v0
+ vmerge.vvm \r7, \d7, \r7, v0
+
+.if \es == 16
+ vsetivli zero, 2, e64, m1, ta, ma
+.elseif \es == 8
+ vsetivli zero, 2, e32, m1, ta, ma
+.endif
+
+ vslideup.vi \d0, \r4, 1
+ vslidedown.vi \d4, \r0, 1
+ vslideup.vi \d1, \r6, 1
+ vslidedown.vi \d5, \r2, 1
+ vslideup.vi \d2, \r5, 1
+ vslidedown.vi \d6, \r1, 1
+ vslideup.vi \d3, \r7, 1
+ vslidedown.vi \d7, \r3, 1
+ vmerge.vvm \d0, \d0, \r0, v0
+ vmerge.vvm \d4, \r4, \d4, v0
+ vmerge.vvm \d1, \d1, \r2, v0
+ vmerge.vvm \d5, \r6, \d5, v0
+ vmerge.vvm \d2, \d2, \r1, v0
+ vmerge.vvm \d6, \r5, \d6, v0
+ vmerge.vvm \d3, \d3, \r3, v0
+ vmerge.vvm \d7, \r7, \d7, v0
+.endm
\ No newline at end of file
diff --git a/libavcodec/tests/riscv/dct.c b/libavcodec/tests/riscv/dct.c
new file mode 100644
index 0000000000..f440c9c326
--- /dev/null
+++ b/libavcodec/tests/riscv/dct.c
@@ -0,0 +1,30 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "libavutil/cpu.h"
+#include "libavcodec/riscv/fdct.h"
+
+static const struct algo fdct_tab_arch[] = {
+#if HAVE_RVV
+ { "rvv", ff_fdct_rvv, FF_IDCT_PERM_NONE, AV_CPU_FLAG_RVV },
+#endif
+ { 0 }
+};
+
--
2.52.0
From ebebe7d39664638c854f9570b6104e2388e82937 Mon Sep 17 00:00:00 2001
From: yuanjia <yuan.jia(a)sanechips.com.cn>
Date: Mon, 10 Aug 2026 12:07:31 +0800
Subject: [PATCH 2/2] fix: resolve whitespace and fate-source errors
---
libavcodec/riscv/fdctdsp_rvv.S | 4 ++--
libavcodec/riscv/rvv.S | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libavcodec/riscv/fdctdsp_rvv.S b/libavcodec/riscv/fdctdsp_rvv.S
index 9906c2c5d2..c324c9089c 100644
--- a/libavcodec/riscv/fdctdsp_rvv.S
+++ b/libavcodec/riscv/fdctdsp_rvv.S
@@ -139,7 +139,7 @@ fdct_consts:
li t3, F_0_298
li t4, F_2_053
li t5, F_3_072
- li t6, F_1_501
+ li t6, F_1_501
vwmul.vx v8, v28, t3
vwmul.vx v10, v29, t4
vwmul.vx v12, v30, t5
@@ -251,4 +251,4 @@ func ff_fdct_rvv, zve32x
vse16.v v23, (t0)
ret
-endfunc
\ No newline at end of file
+endfunc
diff --git a/libavcodec/riscv/rvv.S b/libavcodec/riscv/rvv.S
index 338929b76c..4cdf962302 100644
--- a/libavcodec/riscv/rvv.S
+++ b/libavcodec/riscv/rvv.S
@@ -82,4 +82,4 @@
vmerge.vvm \d6, \r5, \d6, v0
vmerge.vvm \d3, \d3, \r3, v0
vmerge.vvm \d7, \r7, \d7, v0
-.endm
\ No newline at end of file
+.endm
--
2.52.0
1
0
[PR] libaribcaption: emit an empty subtitle for an explicit clear in BITMAP mode (PR #24067)
by 5ym 10 Aug '26
by 5ym 10 Aug '26
10 Aug '26
PR #24067 opened by 5ym
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24067
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24067.patch
An ARIB caption statement whose data units contain only CS (clear screen)
decodes to a caption with region_count == 0. In SUBTITLE_TEXT mode this is
translated into a rect holding "" so that the previous caption is erased.
In SUBTITLE_BITMAP mode nothing is rendered, the function returns 0 and
*got_sub_ptr is left at 0, so the caller never learns that the caption ended.
Broadcasters send such a statement at the end of every caption segment (for
example when going to a commercial break). Combined with wait_duration ==
ARIBCC_DURATION_INDEFINITE, which maps to end_display_time = UINT32_MAX, the
last caption of a segment stays on screen until the next one arrives - in a
real recording that was 22 minutes later.
Report an empty subtitle (num_rects = 0) in that case, which sub2video and
the usual subtitle consumers already treat as "erase".
# Summary of changes
Briefly describe what this PR does and why.
<!--
If this PR requires new FATE test samples, attach them to the PR and
list their target paths below (relative to the fate-suite root).
Attached filenames must match the sample's filename:
```fate-samples
# e.g. vorbis/new-sample.ogg
```
-->
From db032398dd3ba29ecda20ad48f722cf72498dc15 Mon Sep 17 00:00:00 2001
From: Ruk Doe <info(a)doany.io>
Date: Mon, 10 Aug 2026 13:42:57 +0900
Subject: [PATCH] libaribcaption: emit an empty subtitle for an explicit clear
in BITMAP mode
An ARIB caption statement whose data units contain only CS (clear screen)
decodes to a caption with region_count == 0. In SUBTITLE_TEXT mode this is
translated into a rect holding "" so that the previous caption is erased.
In SUBTITLE_BITMAP mode nothing is rendered, the function returns 0 and
*got_sub_ptr is left at 0, so the caller never learns that the caption ended.
Broadcasters send such a statement at the end of every caption segment (for
example when going to a commercial break). Combined with wait_duration ==
ARIBCC_DURATION_INDEFINITE, which maps to end_display_time = UINT32_MAX, the
last caption of a segment stays on screen until the next one arrives - in a
real recording that was 22 minutes later.
Report an empty subtitle (num_rects = 0) in that case, which sub2video and
the usual subtitle consumers already treat as "erase".
---
libavcodec/libaribcaption.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/libavcodec/libaribcaption.c b/libavcodec/libaribcaption.c
index 66d18b9d38..739e048842 100644
--- a/libavcodec/libaribcaption.c
+++ b/libavcodec/libaribcaption.c
@@ -360,6 +360,14 @@ static int aribcaption_trans_bitmap_subtitle(ARIBCaptionContext *ctx)
case ARIBCC_RENDER_STATUS_NO_IMAGE:
ff_dlog(ctx, "no image\n");
+ /* A caption carrying no region is an explicit clear screen (CS).
+ Report an empty subtitle so that the previously displayed bitmap
+ is erased; the TEXT path already does this by emitting "". */
+ if (ctx->caption.region_count == 0) {
+ sub->format = 0; /* graphic */
+ sub->num_rects = 0;
+ return 1;
+ }
return 0;
case ARIBCC_RENDER_STATUS_ERROR:
@@ -377,6 +385,11 @@ static int aribcaption_trans_bitmap_subtitle(ARIBCaptionContext *ctx)
if (!ctx->render_result.image_count || ctx->render_result.images == NULL) {
aribcc_render_result_cleanup(&ctx->render_result);
ff_dlog(ctx, "no image (%d)\n", ctx->render_result.image_count);
+ if (ctx->caption.region_count == 0) {
+ sub->format = 0; /* graphic */
+ sub->num_rects = 0;
+ return 1;
+ }
return 0;
}
--
2.52.0
1
0
10 Aug '26
PR #24066 opened by mkver
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24066
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24066.patch
When porting the AARCH64 functions, I noticed that ff_h264_idct_add16_neon, ff_h264_idct_add16intra_neon and ff_h264_idct_add8_neon (all these functions call either ff_h264_idct_dc_add_neon or ff_h264_idct_add_neon) restore the stride parameter in the loop calling the other functions, although this seems to be unnecessary, as these callers do not modify their stride register at all.
From 7bfc57f36d84ebbe2b6f9fd89cb901083bf3efa2 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt(a)outlook.com>
Date: Mon, 10 Aug 2026 03:20:51 +0200
Subject: [PATCH] avcodec/h264dsp: Use ptrdiff_t for stride in idct functions
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt(a)outlook.com>
---
libavcodec/aarch64/h264dsp_init_aarch64.c | 16 +++++-----
libavcodec/aarch64/h264idct_neon.S | 18 +++++------
libavcodec/arm/h264dsp_init_arm.c | 28 ++++++++---------
libavcodec/h264_mb.c | 6 ++--
libavcodec/h264_mb_template.c | 2 +-
libavcodec/h264addpx_template.c | 4 +--
libavcodec/h264dsp.h | 20 ++++++------
libavcodec/h264idct.h | 19 ++++++------
libavcodec/h264idct_template.c | 25 +++++++++------
libavcodec/loongarch/h264dsp_lasx.c | 4 +--
libavcodec/loongarch/h264dsp_loongarch.h | 36 ++++++++++-----------
libavcodec/loongarch/h264idct.S | 10 +++---
libavcodec/loongarch/h264idct_loongarch.c | 12 +++----
libavcodec/mips/h264dsp_mips.h | 38 +++++++++++------------
libavcodec/mips/h264dsp_mmi.c | 20 ++++++------
libavcodec/mips/h264idct_msa.c | 22 ++++++-------
libavcodec/ppc/h264dsp.c | 22 ++++++-------
libavcodec/riscv/h264dsp_init.c | 26 ++++++++--------
libavcodec/x86/h264_idct.asm | 23 +++++---------
libavcodec/x86/h264_idct_10bit.asm | 29 ++++++-----------
libavcodec/x86/h264dsp_init.c | 6 ++--
tests/checkasm/h264dsp.c | 8 ++---
22 files changed, 190 insertions(+), 204 deletions(-)
diff --git a/libavcodec/aarch64/h264dsp_init_aarch64.c b/libavcodec/aarch64/h264dsp_init_aarch64.c
index c684574320..e4b3aac8ce 100644
--- a/libavcodec/aarch64/h264dsp_init_aarch64.c
+++ b/libavcodec/aarch64/h264dsp_init_aarch64.c
@@ -65,22 +65,22 @@ void ff_biweight_h264_pixels_4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride
int height, int log2_den, int weightd,
int weights, int offset);
-void ff_h264_idct_add_neon(uint8_t *dst, int16_t *block, int stride);
-void ff_h264_idct_dc_add_neon(uint8_t *dst, int16_t *block, int stride);
+void ff_h264_idct_add_neon(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+void ff_h264_idct_dc_add_neon(uint8_t *dst, int16_t *block, ptrdiff_t stride);
void ff_h264_idct_add16_neon(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8]);
void ff_h264_idct_add16intra_neon(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8]);
void ff_h264_idct_add8_neon(uint8_t **dest, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[15 * 8]);
-void ff_h264_idct8_add_neon(uint8_t *dst, int16_t *block, int stride);
-void ff_h264_idct8_dc_add_neon(uint8_t *dst, int16_t *block, int stride);
+void ff_h264_idct8_add_neon(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+void ff_h264_idct8_dc_add_neon(uint8_t *dst, int16_t *block, ptrdiff_t stride);
void ff_h264_idct8_add4_neon(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8]);
void ff_h264_v_loop_filter_luma_neon_10(uint8_t *pix, ptrdiff_t stride, int alpha,
diff --git a/libavcodec/aarch64/h264idct_neon.S b/libavcodec/aarch64/h264idct_neon.S
index 3f7ff2c49e..4e2f98b1da 100644
--- a/libavcodec/aarch64/h264idct_neon.S
+++ b/libavcodec/aarch64/h264idct_neon.S
@@ -26,7 +26,6 @@ function ff_h264_idct_add_neon, export=1
.L_ff_h264_idct_add_neon:
AARCH64_VALID_CALL_TARGET
ld1 {v0.4h, v1.4h, v2.4h, v3.4h}, [x1]
- sxtw x2, w2
movi v30.8h, #0
add v4.4h, v0.4h, v2.4h
@@ -81,7 +80,6 @@ endfunc
function ff_h264_idct_dc_add_neon, export=1
.L_ff_h264_idct_dc_add_neon:
AARCH64_VALID_CALL_TARGET
- sxtw x2, w2
mov w3, #0
ld1r {v2.8h}, [x1]
strh w3, [x1]
@@ -107,12 +105,12 @@ function ff_h264_idct_add16_neon, export=1
mov x6, x0 // dest
mov x5, x1 // block_offset
mov x1, x2 // block
- mov w9, w3 // stride
+ mov x9, x3 // stride
movrel x7, scan8
mov x10, #16
movrel x13, .L_ff_h264_idct_dc_add_neon
movrel x14, .L_ff_h264_idct_add_neon
-1: mov w2, w9
+1: mov x2, x9
ldrb w3, [x7], #1
ldrsw x0, [x5], #4
ldrb w3, [x4, w3, uxtw]
@@ -134,12 +132,12 @@ function ff_h264_idct_add16intra_neon, export=1
mov x6, x0 // dest
mov x5, x1 // block_offset
mov x1, x2 // block
- mov w9, w3 // stride
+ mov x9, x3 // stride
movrel x7, scan8
mov x10, #16
movrel x13, .L_ff_h264_idct_dc_add_neon
movrel x14, .L_ff_h264_idct_add_neon
-1: mov w2, w9
+1: mov x2, x9
ldrb w3, [x7], #1
ldrsw x0, [x5], #4
ldrb w3, [x4, w3, uxtw]
@@ -162,13 +160,13 @@ function ff_h264_idct_add8_neon, export=1
ldp x6, x15, [x0] // dest[0], dest[1]
add x5, x1, #16*4 // block_offset
add x9, x2, #16*32 // block
- mov w19, w3 // stride
+ mov x19, x3 // stride
movrel x13, .L_ff_h264_idct_dc_add_neon
movrel x14, .L_ff_h264_idct_add_neon
movrel x7, scan8, 16
mov x10, #0
mov x11, #16
-1: mov w2, w19
+1: mov x2, x19
ldrb w3, [x7, x10] // scan8[i]
ldrsw x0, [x5, x10, lsl #2] // block_offset[i]
ldrb w3, [x4, w3, uxtw] // nnzc[ scan8[i] ]
@@ -268,7 +266,6 @@ function ff_h264_idct8_add_neon, export=1
.L_ff_h264_idct8_add_neon:
AARCH64_VALID_CALL_TARGET
movi v19.8h, #0
- sxtw x2, w2
ld1 {v24.8h, v25.8h}, [x1]
st1 {v19.8h}, [x1], #16
st1 {v19.8h}, [x1], #16
@@ -333,7 +330,6 @@ function ff_h264_idct8_dc_add_neon, export=1
.L_ff_h264_idct8_dc_add_neon:
AARCH64_VALID_CALL_TARGET
mov w3, #0
- sxtw x2, w2
ld1r {v31.8h}, [x1]
strh w3, [x1]
ld1 {v0.8b}, [x0], x2
@@ -378,7 +374,7 @@ function ff_h264_idct8_add4_neon, export=1
mov x6, x0
mov x5, x1
mov x1, x2
- mov w2, w3
+ mov x2, x3
movrel x7, scan8
mov w10, #16
movrel x13, .L_ff_h264_idct8_dc_add_neon
diff --git a/libavcodec/arm/h264dsp_init_arm.c b/libavcodec/arm/h264dsp_init_arm.c
index 050ceb90bf..80c2620637 100644
--- a/libavcodec/arm/h264dsp_init_arm.c
+++ b/libavcodec/arm/h264dsp_init_arm.c
@@ -36,39 +36,39 @@ void ff_h264_h_loop_filter_chroma_neon(uint8_t *pix, ptrdiff_t stride, int alpha
void ff_h264_h_loop_filter_chroma422_neon(uint8_t *pix, ptrdiff_t stride, int alpha,
int beta, int8_t *tc0);
-void ff_weight_h264_pixels_16_neon(uint8_t *dst, int stride, int height,
+void ff_weight_h264_pixels_16_neon(uint8_t *dst, ptrdiff_t stride, int height,
int log2_den, int weight, int offset);
-void ff_weight_h264_pixels_8_neon(uint8_t *dst, int stride, int height,
+void ff_weight_h264_pixels_8_neon(uint8_t *dst, ptrdiff_t stride, int height,
int log2_den, int weight, int offset);
-void ff_weight_h264_pixels_4_neon(uint8_t *dst, int stride, int height,
+void ff_weight_h264_pixels_4_neon(uint8_t *dst, ptrdiff_t stride, int height,
int log2_den, int weight, int offset);
-void ff_biweight_h264_pixels_16_neon(uint8_t *dst, uint8_t *src, int stride,
+void ff_biweight_h264_pixels_16_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int height, int log2_den, int weightd,
int weights, int offset);
-void ff_biweight_h264_pixels_8_neon(uint8_t *dst, uint8_t *src, int stride,
+void ff_biweight_h264_pixels_8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int height, int log2_den, int weightd,
int weights, int offset);
-void ff_biweight_h264_pixels_4_neon(uint8_t *dst, uint8_t *src, int stride,
+void ff_biweight_h264_pixels_4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int height, int log2_den, int weightd,
int weights, int offset);
-void ff_h264_idct_add_neon(uint8_t *dst, int16_t *block, int stride);
-void ff_h264_idct_dc_add_neon(uint8_t *dst, int16_t *block, int stride);
+void ff_h264_idct_add_neon(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+void ff_h264_idct_dc_add_neon(uint8_t *dst, int16_t *block, ptrdiff_t stride);
void ff_h264_idct_add16_neon(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8]);
void ff_h264_idct_add16intra_neon(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8]);
void ff_h264_idct_add8_neon(uint8_t **dest, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[15 * 8]);
-void ff_h264_idct8_add_neon(uint8_t *dst, int16_t *block, int stride);
-void ff_h264_idct8_dc_add_neon(uint8_t *dst, int16_t *block, int stride);
+void ff_h264_idct8_add_neon(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+void ff_h264_idct8_dc_add_neon(uint8_t *dst, int16_t *block, ptrdiff_t stride);
void ff_h264_idct8_add4_neon(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8]);
static av_cold void h264dsp_init_neon(H264DSPContext *c, const int bit_depth,
diff --git a/libavcodec/h264_mb.c b/libavcodec/h264_mb.c
index 67fa980de3..aa87db2449 100644
--- a/libavcodec/h264_mb.c
+++ b/libavcodec/h264_mb.c
@@ -620,8 +620,8 @@ static av_always_inline void hl_decode_mb_predict_luma(const H264Context *h,
int linesize,
uint8_t *dest_y, int p)
{
- void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
- void (*idct_dc_add)(uint8_t *dst, int16_t *block, int stride);
+ void (*idct_add)(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+ void (*idct_dc_add)(uint8_t *dst, int16_t *block, ptrdiff_t stride);
int i;
int qscale = p == 0 ? sl->qscale : sl->chroma_qp[p - 1];
block_offset += 16 * p;
@@ -733,7 +733,7 @@ static av_always_inline void hl_decode_mb_idct_luma(const H264Context *h, H264Sl
int linesize,
uint8_t *dest_y, int p)
{
- void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
+ void (*idct_add)(uint8_t *dst, int16_t *block, ptrdiff_t stride);
int i;
block_offset += 16 * p;
if (!IS_INTRA4x4(mb_type)) {
diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c
index ee8c81a10c..050e1db783 100644
--- a/libavcodec/h264_mb_template.c
+++ b/libavcodec/h264_mb_template.c
@@ -49,7 +49,7 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
int i, j;
const int *block_offset = &h->block_offset[0];
const int transform_bypass = !SIMPLE && (sl->qscale == 0 && h->ps.sps->transform_bypass);
- void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
+ void (*idct_add)(uint8_t *dst, int16_t *block, ptrdiff_t stride);
const int block_h = 16 >> h->chroma_y_shift;
const int chroma422 = CHROMA422(h);
diff --git a/libavcodec/h264addpx_template.c b/libavcodec/h264addpx_template.c
index 9a1e6a2f2f..b04430edda 100644
--- a/libavcodec/h264addpx_template.c
+++ b/libavcodec/h264addpx_template.c
@@ -27,7 +27,7 @@
#include "bit_depth_template.c"
-static void FUNCC(ff_h264_add_pixels4)(uint8_t *_dst, int16_t *_src, int stride)
+static void FUNCC(ff_h264_add_pixels4)(uint8_t *_dst, int16_t *_src, ptrdiff_t stride)
{
int i;
pixel *dst = (pixel *) _dst;
@@ -47,7 +47,7 @@ static void FUNCC(ff_h264_add_pixels4)(uint8_t *_dst, int16_t *_src, int stride)
memset(_src, 0, sizeof(dctcoef) * 16);
}
-static void FUNCC(ff_h264_add_pixels8)(uint8_t *_dst, int16_t *_src, int stride)
+static void FUNCC(ff_h264_add_pixels8)(uint8_t *_dst, int16_t *_src, ptrdiff_t stride)
{
int i;
pixel *dst = (pixel *) _dst;
diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
index f40d324a4e..1ade25e4ac 100644
--- a/libavcodec/h264dsp.h
+++ b/libavcodec/h264dsp.h
@@ -79,33 +79,33 @@ typedef struct H264DSPContext {
/* IDCT */
void (*idct_add)(uint8_t *dst /*align 4*/,
- int16_t *block /*align 16*/, int stride);
+ int16_t *block /*align 16*/, ptrdiff_t stride);
void (*idct8_add)(uint8_t *dst /*align 8*/,
- int16_t *block /*align 16*/, int stride);
+ int16_t *block /*align 16*/, ptrdiff_t stride);
void (*idct_dc_add)(uint8_t *dst /*align 4*/,
- int16_t *block /*align 16*/, int stride);
+ int16_t *block /*align 16*/, ptrdiff_t stride);
void (*idct8_dc_add)(uint8_t *dst /*align 8*/,
- int16_t *block /*align 16*/, int stride);
+ int16_t *block /*align 16*/, ptrdiff_t stride);
void (*idct_add16)(uint8_t *dst /*align 16*/, const int *blockoffset,
- int16_t *block /*align 16*/, int stride,
+ int16_t *block /*align 16*/, ptrdiff_t stride,
const uint8_t nnzc[5 * 8]);
void (*idct8_add4)(uint8_t *dst /*align 16*/, const int *blockoffset,
- int16_t *block /*align 16*/, int stride,
+ int16_t *block /*align 16*/, ptrdiff_t stride,
const uint8_t nnzc[5 * 8]);
void (*idct_add8)(uint8_t **dst /*align 16*/, const int *blockoffset,
- int16_t *block /*align 16*/, int stride,
+ int16_t *block /*align 16*/, ptrdiff_t stride,
const uint8_t nnzc[15 * 8]);
void (*idct_add16intra)(uint8_t *dst /*align 16*/, const int *blockoffset,
int16_t *block /*align 16*/,
- int stride, const uint8_t nnzc[5 * 8]);
+ ptrdiff_t stride, const uint8_t nnzc[5 * 8]);
void (*luma_dc_dequant_idct)(int16_t *output,
int16_t *input /*align 16*/, int qmul);
void (*chroma_dc_dequant_idct)(int16_t *block, int qmul);
/* bypass-transform */
- void (*add_pixels8_clear)(uint8_t *dst, int16_t *block, int stride);
- void (*add_pixels4_clear)(uint8_t *dst, int16_t *block, int stride);
+ void (*add_pixels8_clear)(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+ void (*add_pixels4_clear)(uint8_t *dst, int16_t *block, ptrdiff_t stride);
/**
* Search buf from the start for up to size bytes. Return the index
diff --git a/libavcodec/h264idct.h b/libavcodec/h264idct.h
index 42e93ed17a..53629e1aac 100644
--- a/libavcodec/h264idct.h
+++ b/libavcodec/h264idct.h
@@ -19,18 +19,19 @@
#ifndef AVCODEC_H264IDCT_H
#define AVCODEC_H264IDCT_H
+#include <stddef.h>
#include <stdint.h>
#define H264_IDCT(depth) \
-void ff_h264_idct8_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
-void ff_h264_idct_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
-void ff_h264_idct8_dc_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
-void ff_h264_idct_dc_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
-void ff_h264_idct_add16_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[5 * 8]);\
-void ff_h264_idct_add16intra_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[5 * 8]);\
-void ff_h264_idct8_add4_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[5 * 8]);\
-void ff_h264_idct_add8_422_ ## depth ## _c(uint8_t **dest, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[15 * 8]);\
-void ff_h264_idct_add8_ ## depth ## _c(uint8_t **dest, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[15 * 8]);\
+void ff_h264_idct8_add_ ## depth ## _c(uint8_t *dst, int16_t *block, ptrdiff_t stride);\
+void ff_h264_idct_add_ ## depth ## _c(uint8_t *dst, int16_t *block, ptrdiff_t stride);\
+void ff_h264_idct8_dc_add_ ## depth ## _c(uint8_t *dst, int16_t *block, ptrdiff_t stride);\
+void ff_h264_idct_dc_add_ ## depth ## _c(uint8_t *dst, int16_t *block, ptrdiff_t stride);\
+void ff_h264_idct_add16_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, ptrdiff_t stride, const uint8_t nnzc[5 * 8]);\
+void ff_h264_idct_add16intra_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, ptrdiff_t stride, const uint8_t nnzc[5 * 8]);\
+void ff_h264_idct8_add4_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, ptrdiff_t stride, const uint8_t nnzc[5 * 8]);\
+void ff_h264_idct_add8_422_ ## depth ## _c(uint8_t **dest, const int *blockoffset, int16_t *block, ptrdiff_t stride, const uint8_t nnzc[15 * 8]);\
+void ff_h264_idct_add8_ ## depth ## _c(uint8_t **dest, const int *blockoffset, int16_t *block, ptrdiff_t stride, const uint8_t nnzc[15 * 8]);\
H264_IDCT( 8)
H264_IDCT( 9)
diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c
index 64f5faddca..92be515c92 100644
--- a/libavcodec/h264idct_template.c
+++ b/libavcodec/h264idct_template.c
@@ -30,7 +30,7 @@
#include "h264_parse.h"
#include "h264idct.h"
-void FUNCC(ff_h264_idct_add)(uint8_t *_dst, int16_t *_block, int stride)
+void FUNCC(ff_h264_idct_add)(uint8_t *_dst, int16_t *_block, ptrdiff_t stride)
{
int i;
pixel *dst = (pixel*)_dst;
@@ -66,7 +66,8 @@ void FUNCC(ff_h264_idct_add)(uint8_t *_dst, int16_t *_block, int stride)
memset(block, 0, 16 * sizeof(dctcoef));
}
-void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, int16_t *_block, int stride){
+void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, int16_t *_block, ptrdiff_t stride)
+{
int i;
pixel *dst = (pixel*)_dst;
dctcoef *block = (dctcoef*)_block;
@@ -141,7 +142,8 @@ void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, int16_t *_block, int stride){
}
// assumes all AC coefs are 0
-void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, int16_t *_block, int stride){
+void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, int16_t *_block, ptrdiff_t stride)
+{
int i, j;
pixel *dst = (pixel*)_dst;
dctcoef *block = (dctcoef*)_block;
@@ -156,7 +158,8 @@ void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, int16_t *_block, int stride){
}
}
-void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, int16_t *_block, int stride){
+void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, int16_t *_block, ptrdiff_t stride)
+{
int i, j;
pixel *dst = (pixel*)_dst;
dctcoef *block = (dctcoef*)_block;
@@ -172,7 +175,7 @@ void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, int16_t *_block, int stride){
}
void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8])
{
int i;
@@ -186,7 +189,7 @@ void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset,
}
void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8])
{
int i;
@@ -197,7 +200,7 @@ void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset,
}
void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8])
{
int i;
@@ -210,7 +213,9 @@ void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset,
}
}
-void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, int16_t *block,
+ ptrdiff_t stride, const uint8_t nnzc[15*8])
+{
int i, j;
for(j=1; j<3; j++){
for(i=j*16; i<j*16+4; i++){
@@ -222,7 +227,9 @@ void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, int16_t *
}
}
-void FUNCC(ff_h264_idct_add8_422)(uint8_t **dest, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct_add8_422)(uint8_t **dest, const int *block_offset,
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[15*8])
+{
int i, j;
for(j=1; j<3; j++){
diff --git a/libavcodec/loongarch/h264dsp_lasx.c b/libavcodec/loongarch/h264dsp_lasx.c
index 5205cc849f..c2c9ea7f0f 100644
--- a/libavcodec/loongarch/h264dsp_lasx.c
+++ b/libavcodec/loongarch/h264dsp_lasx.c
@@ -699,7 +699,7 @@ void ff_h264_v_lpf_luma_intra_8_lasx(uint8_t *data, ptrdiff_t img_width,
}
}
-void ff_h264_add_pixels4_8_lasx(uint8_t *_dst, int16_t *_src, int stride)
+void ff_h264_add_pixels4_8_lasx(uint8_t *_dst, int16_t *_src, ptrdiff_t stride)
{
__m256i src0, dst0, dst1, dst2, dst3, zero;
__m256i tmp0, tmp1;
@@ -726,7 +726,7 @@ void ff_h264_add_pixels4_8_lasx(uint8_t *_dst, int16_t *_src, int stride)
__lasx_xvst(zero, _src, 0);
}
-void ff_h264_add_pixels8_8_lasx(uint8_t *_dst, int16_t *_src, int stride)
+void ff_h264_add_pixels8_8_lasx(uint8_t *_dst, int16_t *_src, ptrdiff_t stride)
{
__m256i src0, src1, src2, src3;
__m256i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
diff --git a/libavcodec/loongarch/h264dsp_loongarch.h b/libavcodec/loongarch/h264dsp_loongarch.h
index e17522dfe0..8d99910723 100644
--- a/libavcodec/loongarch/h264dsp_loongarch.h
+++ b/libavcodec/loongarch/h264dsp_loongarch.h
@@ -26,25 +26,25 @@
#include "libavcodec/h264dec.h"
#include "config.h"
-void ff_h264_idct_add_8_lsx(uint8_t *dst, int16_t *src, int dst_stride);
-void ff_h264_idct8_add_8_lsx(uint8_t *dst, int16_t *src, int dst_stride);
-void ff_h264_idct_dc_add_8_lsx(uint8_t *dst, int16_t *src, int dst_stride);
-void ff_h264_idct8_dc_add_8_lsx(uint8_t *dst, int16_t *src, int dst_stride);
+void ff_h264_idct_add_8_lsx(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride);
+void ff_h264_idct8_add_8_lsx(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride);
+void ff_h264_idct_dc_add_8_lsx(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride);
+void ff_h264_idct8_dc_add_8_lsx(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride);
void ff_h264_luma_dc_dequant_idct_8_lsx(int16_t *_output, int16_t *_input, int qmul);
void ff_h264_idct_add16_8_lsx(uint8_t *dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8]);
void ff_h264_idct8_add4_8_lsx(uint8_t *dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8]);
void ff_h264_idct_add8_8_lsx(uint8_t **dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8]);
void ff_h264_idct_add8_422_8_lsx(uint8_t **dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8]);
void ff_h264_idct_add16_intra_8_lsx(uint8_t *dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8]);
void ff_h264_h_lpf_luma_8_lsx(uint8_t *src, ptrdiff_t stride,
@@ -84,8 +84,8 @@ void ff_weight_h264_pixels8_8_lsx(uint8_t *src, ptrdiff_t stride,
void ff_weight_h264_pixels4_8_lsx(uint8_t *src, ptrdiff_t stride,
int height, int log2_denom,
int weight_src, int offset);
-void ff_h264_add_pixels4_8_lsx(uint8_t *_dst, int16_t *_src, int stride);
-void ff_h264_add_pixels8_8_lsx(uint8_t *_dst, int16_t *_src, int stride);
+void ff_h264_add_pixels4_8_lsx(uint8_t *_dst, int16_t *_src, ptrdiff_t stride);
+void ff_h264_add_pixels8_8_lsx(uint8_t *_dst, int16_t *_src, ptrdiff_t stride);
void ff_h264_loop_filter_strength_lsx(int16_t bS[2][4][4], uint8_t nnz[40],
int8_t ref[2][40], int16_t mv[2][40][2],
int bidir, int edges, int step,
@@ -101,11 +101,11 @@ void ff_h264_h_lpf_luma_intra_8_lasx(uint8_t *src, ptrdiff_t stride,
void ff_h264_v_lpf_luma_intra_8_lasx(uint8_t *src, ptrdiff_t stride,
int alpha, int beta);
void ff_biweight_h264_pixels16_8_lasx(unsigned char *dst, unsigned char *src,
- long int stride, int height,
+ ptrdiff_t stride, int height,
int log2_denom, int weight_dst,
int weight_src, int offset_in);
void ff_biweight_h264_pixels8_8_lasx(unsigned char *dst, unsigned char *src,
- long int stride, int height,
+ ptrdiff_t stride, int height,
int log2_denom, int weight_dst,
int weight_src, int offset);
void ff_weight_h264_pixels16_8_lasx(uint8_t *src, ptrdiff_t stride,
@@ -114,14 +114,14 @@ void ff_weight_h264_pixels16_8_lasx(uint8_t *src, ptrdiff_t stride,
void ff_weight_h264_pixels8_8_lasx(uint8_t *src, ptrdiff_t stride,
int height, int log2_denom,
int weight_src, int offset);
-void ff_h264_add_pixels4_8_lasx(uint8_t *_dst, int16_t *_src, int stride);
+void ff_h264_add_pixels4_8_lasx(uint8_t *_dst, int16_t *_src, ptrdiff_t stride);
-void ff_h264_add_pixels8_8_lasx(uint8_t *_dst, int16_t *_src, int stride);
-void ff_h264_idct8_add_8_lasx(uint8_t *dst, int16_t *src, int32_t dst_stride);
+void ff_h264_add_pixels8_8_lasx(uint8_t *_dst, int16_t *_src, ptrdiff_t stride);
+void ff_h264_idct8_add_8_lasx(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride);
void ff_h264_idct8_dc_add_8_lasx(uint8_t *dst, int16_t *src,
- int32_t dst_stride);
+ ptrdiff_t dst_stride);
void ff_h264_idct8_add4_8_lasx(uint8_t *dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8]);
void ff_h264_loop_filter_strength_lasx(int16_t bS[2][4][4], uint8_t nnz[40],
int8_t ref[2][40], int16_t mv[2][40][2],
diff --git a/libavcodec/loongarch/h264idct.S b/libavcodec/loongarch/h264idct.S
index f504cfb714..d47c5209ef 100644
--- a/libavcodec/loongarch/h264idct.S
+++ b/libavcodec/loongarch/h264idct.S
@@ -26,7 +26,7 @@
/*
* #define FUNC2(a, b, c) FUNC3(a, b, c)
* #define FUNCC(a) FUNC2(a, BIT_DEPTH, _c)
- * void FUNCC(ff_h264_idct_add)(uint8_t *_dst, int16_t *_block, int stride)
+ * void FUNCC(ff_h264_idct_add)(uint8_t *_dst, int16_t *_block, ptrdiff_t stride)
* LSX optimization is enough for this function.
*/
function ff_h264_idct_add_8_lsx
@@ -88,7 +88,7 @@ endfunc
/*
* #define FUNC2(a, b, c) FUNC3(a, b, c)
* #define FUNCC(a) FUNC2(a, BIT_DEPTH, _c)
- * void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, int16_t *_block, int stride)
+ * void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, int16_t *_block, ptrdiff_t stride)
*/
function ff_h264_idct8_add_8_lsx
ld.h t0, a1, 0
@@ -295,7 +295,7 @@ endfunc
/*
* #define FUNC2(a, b, c) FUNC3(a, b, c)
* #define FUNCC(a) FUNC2(a, BIT_DEPTH, _c)
- * void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, int16_t *_block, int stride)
+ * void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, int16_t *_block, ptrdiff_t stride)
*/
function ff_h264_idct8_add_8_lasx
ld.h t0, a1, 0
@@ -466,7 +466,7 @@ endfunc
/*
* #define FUNC2(a, b, c) FUNC3(a, b, c)
* #define FUNCC(a) FUNC2(a, BIT_DEPTH, _c)
- * void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, int16_t *_block, int stride)
+ * void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, int16_t *_block, ptrdiff_t stride)
* LSX optimization is enough for this function.
*/
function ff_h264_idct_dc_add_8_lsx
@@ -500,7 +500,7 @@ endfunc
/*
* #define FUNC2(a, b, c) FUNC3(a, b, c)
* #define FUNCC(a) FUNC2(a, BIT_DEPTH, _c)
- * void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, int16_t *_block, int stride)
+ * void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, int16_t *_block, ptrdiff_t stride)
*/
function ff_h264_idct8_dc_add_8_lsx
vldrepl.h vr8, a1, 0
diff --git a/libavcodec/loongarch/h264idct_loongarch.c b/libavcodec/loongarch/h264idct_loongarch.c
index 26af45503f..b51f9cd6ec 100644
--- a/libavcodec/loongarch/h264idct_loongarch.c
+++ b/libavcodec/loongarch/h264idct_loongarch.c
@@ -26,7 +26,7 @@
#include "libavcodec/bit_depth_template.c"
void ff_h264_idct_add16_8_lsx(uint8_t *dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t i;
@@ -47,7 +47,7 @@ void ff_h264_idct_add16_8_lsx(uint8_t *dst, const int32_t *blk_offset,
}
void ff_h264_idct8_add4_8_lsx(uint8_t *dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t cnt;
@@ -69,7 +69,7 @@ void ff_h264_idct8_add4_8_lsx(uint8_t *dst, const int32_t *blk_offset,
#if HAVE_LASX
void ff_h264_idct8_add4_8_lasx(uint8_t *dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t cnt;
@@ -91,7 +91,7 @@ void ff_h264_idct8_add4_8_lasx(uint8_t *dst, const int32_t *blk_offset,
#endif // #if HAVE_LASX
void ff_h264_idct_add8_8_lsx(uint8_t **dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t i;
@@ -119,7 +119,7 @@ void ff_h264_idct_add8_8_lsx(uint8_t **dst, const int32_t *blk_offset,
}
void ff_h264_idct_add8_422_8_lsx(uint8_t **dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t i;
@@ -167,7 +167,7 @@ void ff_h264_idct_add8_422_8_lsx(uint8_t **dst, const int32_t *blk_offset,
}
void ff_h264_idct_add16_intra_8_lsx(uint8_t *dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t i;
diff --git a/libavcodec/mips/h264dsp_mips.h b/libavcodec/mips/h264dsp_mips.h
index 4a2a2c2559..2283dd6e17 100644
--- a/libavcodec/mips/h264dsp_mips.h
+++ b/libavcodec/mips/h264dsp_mips.h
@@ -43,28 +43,28 @@ void ff_h264_h_loop_filter_luma_mbaff_msa(uint8_t *src, ptrdiff_t stride,
int32_t alpha, int32_t beta,
int8_t *tc0);
-void ff_h264_idct_add_msa(uint8_t *dst, int16_t *src, int32_t dst_stride);
+void ff_h264_idct_add_msa(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride);
void ff_h264_idct4x4_addblk_dc_msa(uint8_t *dst, int16_t *src,
- int32_t dst_stride);
+ ptrdiff_t dst_stride);
void ff_h264_deq_idct_luma_dc_msa(int16_t *dst, int16_t *src,
int32_t de_q_val);
void ff_h264_idct_add16_msa(uint8_t *dst, const int32_t *blk_offset,
- int16_t *block, int32_t stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8]);
void ff_h264_idct_add16_intra_msa(uint8_t *dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nnzc[5 * 8]);
void ff_h264_idct_add8_msa(uint8_t **dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nnzc[15 * 8]);
void ff_h264_idct_add8_422_msa(uint8_t **dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nnzc[15 * 8]);
-void ff_h264_idct8_addblk_msa(uint8_t *dst, int16_t *src, int32_t dst_stride);
+void ff_h264_idct8_addblk_msa(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride);
void ff_h264_idct8_dc_addblk_msa(uint8_t *dst, int16_t *src,
- int32_t dst_stride);
+ ptrdiff_t dst_stride);
void ff_h264_idct8_add4_msa(uint8_t *dst, const int *blk_offset,
- int16_t *blk, int dst_stride,
+ int16_t *blk, ptrdiff_t dst_stride,
const uint8_t nnzc[5 * 8]);
void ff_h264_h_lpf_luma_intra_msa(uint8_t *src, ptrdiff_t stride,
@@ -323,21 +323,21 @@ void ff_h264_loop_filter_strength_msa(int16_t bS[2][4][4], uint8_t nnz[40],
int8_t ref[2][40], int16_t mv[2][40][2], int bidir, int edges,
int step, int mask_mv0, int mask_mv1, int field);
-void ff_h264_add_pixels4_8_mmi(uint8_t *_dst, int16_t *_src, int stride);
-void ff_h264_idct_add_8_mmi(uint8_t *dst, int16_t *block, int stride);
-void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride);
-void ff_h264_idct_dc_add_8_mmi(uint8_t *dst, int16_t *block, int stride);
-void ff_h264_idct8_dc_add_8_mmi(uint8_t *dst, int16_t *block, int stride);
+void ff_h264_add_pixels4_8_mmi(uint8_t *_dst, int16_t *_src, ptrdiff_t stride);
+void ff_h264_idct_add_8_mmi(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+void ff_h264_idct_dc_add_8_mmi(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+void ff_h264_idct8_dc_add_8_mmi(uint8_t *dst, int16_t *block, ptrdiff_t stride);
void ff_h264_idct_add16_8_mmi(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride, const uint8_t nnzc[5 * 8]);
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[5 * 8]);
void ff_h264_idct_add16intra_8_mmi(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride, const uint8_t nnzc[5 * 8]);
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[5 * 8]);
void ff_h264_idct8_add4_8_mmi(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride, const uint8_t nnzc[5 * 8]);
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[5 * 8]);
void ff_h264_idct_add8_8_mmi(uint8_t **dest, const int *block_offset,
- int16_t *block, int stride, const uint8_t nnzc[15*8]);
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[15*8]);
void ff_h264_idct_add8_422_8_mmi(uint8_t **dest, const int *block_offset,
- int16_t *block, int stride, const uint8_t nnzc[15*8]);
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[15*8]);
void ff_h264_luma_dc_dequant_idct_8_mmi(int16_t *output, int16_t *input,
int qmul);
diff --git a/libavcodec/mips/h264dsp_mmi.c b/libavcodec/mips/h264dsp_mmi.c
index bae1052dcf..bee4e84e37 100644
--- a/libavcodec/mips/h264dsp_mmi.c
+++ b/libavcodec/mips/h264dsp_mmi.c
@@ -28,7 +28,7 @@
#include "libavutil/mips/mmiutils.h"
#include "libavutil/mem_internal.h"
-void ff_h264_add_pixels4_8_mmi(uint8_t *dst, int16_t *src, int stride)
+void ff_h264_add_pixels4_8_mmi(uint8_t *dst, int16_t *src, ptrdiff_t stride)
{
double ftmp[9];
DECLARE_VAR_LOW32;
@@ -76,7 +76,7 @@ void ff_h264_add_pixels4_8_mmi(uint8_t *dst, int16_t *src, int stride)
}
-void ff_h264_idct_add_8_mmi(uint8_t *dst, int16_t *block, int stride)
+void ff_h264_idct_add_8_mmi(uint8_t *dst, int16_t *block, ptrdiff_t stride)
{
double ftmp[12];
uint64_t tmp[1];
@@ -168,7 +168,7 @@ void ff_h264_idct_add_8_mmi(uint8_t *dst, int16_t *block, int stride)
}
-void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride)
+void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, ptrdiff_t stride)
{
double ftmp[16];
uint64_t tmp[7];
@@ -636,7 +636,7 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride)
}
-void ff_h264_idct_dc_add_8_mmi(uint8_t *dst, int16_t *block, int stride)
+void ff_h264_idct_dc_add_8_mmi(uint8_t *dst, int16_t *block, ptrdiff_t stride)
{
int dc = (block[0] + 32) >> 6;
double ftmp[6];
@@ -680,7 +680,7 @@ void ff_h264_idct_dc_add_8_mmi(uint8_t *dst, int16_t *block, int stride)
);
}
-void ff_h264_idct8_dc_add_8_mmi(uint8_t *dst, int16_t *block, int stride)
+void ff_h264_idct8_dc_add_8_mmi(uint8_t *dst, int16_t *block, ptrdiff_t stride)
{
int dc = (block[0] + 32) >> 6;
double ftmp[10];
@@ -766,7 +766,7 @@ void ff_h264_idct8_dc_add_8_mmi(uint8_t *dst, int16_t *block, int stride)
}
void ff_h264_idct_add16_8_mmi(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8])
{
int i;
@@ -784,7 +784,7 @@ void ff_h264_idct_add16_8_mmi(uint8_t *dst, const int *block_offset,
}
void ff_h264_idct_add16intra_8_mmi(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride, const uint8_t nnzc[5 * 8])
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[5 * 8])
{
int i;
for(i=0; i<16; i++){
@@ -797,7 +797,7 @@ void ff_h264_idct_add16intra_8_mmi(uint8_t *dst, const int *block_offset,
}
void ff_h264_idct8_add4_8_mmi(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride, const uint8_t nnzc[5 * 8])
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[5 * 8])
{
int i;
for(i=0; i<16; i+=4){
@@ -814,7 +814,7 @@ void ff_h264_idct8_add4_8_mmi(uint8_t *dst, const int *block_offset,
}
void ff_h264_idct_add8_8_mmi(uint8_t **dest, const int *block_offset,
- int16_t *block, int stride, const uint8_t nnzc[15*8])
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[15*8])
{
int i, j;
for(j=1; j<3; j++){
@@ -830,7 +830,7 @@ void ff_h264_idct_add8_8_mmi(uint8_t **dest, const int *block_offset,
}
void ff_h264_idct_add8_422_8_mmi(uint8_t **dest, const int *block_offset,
- int16_t *block, int stride, const uint8_t nnzc[15*8])
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[15*8])
{
int i, j;
diff --git a/libavcodec/mips/h264idct_msa.c b/libavcodec/mips/h264idct_msa.c
index 1a20a3e30e..cfa375f17d 100644
--- a/libavcodec/mips/h264idct_msa.c
+++ b/libavcodec/mips/h264idct_msa.c
@@ -108,7 +108,7 @@ static void avc_deq_idct_luma_dc_msa(int16_t *dst, int16_t *src,
#undef DC_DEST_STRIDE
}
-static void avc_idct8_addblk_msa(uint8_t *dst, int16_t *src, int32_t dst_stride)
+static void avc_idct8_addblk_msa(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride)
{
v8i16 src0, src1, src2, src3, src4, src5, src6, src7;
v8i16 vec0, vec1, vec2, vec3;
@@ -240,7 +240,7 @@ static void avc_idct8_addblk_msa(uint8_t *dst, int16_t *src, int32_t dst_stride)
}
static void avc_idct8_dc_addblk_msa(uint8_t *dst, int16_t *src,
- int32_t dst_stride)
+ ptrdiff_t dst_stride)
{
int32_t dc_val;
v16i8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
@@ -269,7 +269,7 @@ static void avc_idct8_dc_addblk_msa(uint8_t *dst, int16_t *src,
ST_D8(dst0, dst1, dst2, dst3, 0, 1, 0, 1, 0, 1, 0, 1, dst, dst_stride)
}
-void ff_h264_idct_add_msa(uint8_t *dst, int16_t *src, int32_t dst_stride)
+void ff_h264_idct_add_msa(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride)
{
uint32_t src0_m, src1_m, src2_m, src3_m, out0_m, out1_m, out2_m, out3_m;
v16i8 dst0_m = { 0 };
@@ -311,13 +311,13 @@ void ff_h264_idct_add_msa(uint8_t *dst, int16_t *src, int32_t dst_stride)
}
void ff_h264_idct8_addblk_msa(uint8_t *dst, int16_t *src,
- int32_t dst_stride)
+ ptrdiff_t dst_stride)
{
avc_idct8_addblk_msa(dst, src, dst_stride);
}
void ff_h264_idct4x4_addblk_dc_msa(uint8_t *dst, int16_t *src,
- int32_t dst_stride)
+ ptrdiff_t dst_stride)
{
v16u8 pred = { 0 };
v16i8 out;
@@ -339,14 +339,14 @@ void ff_h264_idct4x4_addblk_dc_msa(uint8_t *dst, int16_t *src,
}
void ff_h264_idct8_dc_addblk_msa(uint8_t *dst, int16_t *src,
- int32_t dst_stride)
+ ptrdiff_t dst_stride)
{
avc_idct8_dc_addblk_msa(dst, src, dst_stride);
}
void ff_h264_idct_add16_msa(uint8_t *dst,
const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[5 * 8])
{
int32_t i;
@@ -368,7 +368,7 @@ void ff_h264_idct_add16_msa(uint8_t *dst,
}
void ff_h264_idct8_add4_msa(uint8_t *dst, const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[5 * 8])
{
int32_t cnt;
@@ -391,7 +391,7 @@ void ff_h264_idct8_add4_msa(uint8_t *dst, const int32_t *blk_offset,
void ff_h264_idct_add8_msa(uint8_t **dst,
const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t i, j;
@@ -412,7 +412,7 @@ void ff_h264_idct_add8_msa(uint8_t **dst,
void ff_h264_idct_add8_422_msa(uint8_t **dst,
const int32_t *blk_offset,
- int16_t *block, int32_t dst_stride,
+ int16_t *block, ptrdiff_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t i, j;
@@ -447,7 +447,7 @@ void ff_h264_idct_add8_422_msa(uint8_t **dst,
void ff_h264_idct_add16_intra_msa(uint8_t *dst,
const int32_t *blk_offset,
int16_t *block,
- int32_t dst_stride,
+ ptrdiff_t dst_stride,
const uint8_t nzc[5 * 8])
{
int32_t i;
diff --git a/libavcodec/ppc/h264dsp.c b/libavcodec/ppc/h264dsp.c
index 22d3db64a1..d832e7f01c 100644
--- a/libavcodec/ppc/h264dsp.c
+++ b/libavcodec/ppc/h264dsp.c
@@ -83,7 +83,7 @@
va_u32 = vec_splat((vec_u32)va_u8, 0); \
vec_ste(va_u32, element, (uint32_t*)dst);
-static void h264_idct_add_altivec(uint8_t *dst, int16_t *block, int stride)
+static void h264_idct_add_altivec(uint8_t *dst, int16_t *block, ptrdiff_t stride)
{
vec_s16 va0, va1, va2, va3;
vec_s16 vz0, vz1, vz2, vz3;
@@ -215,7 +215,7 @@ static void h264_idct_add_altivec(uint8_t *dst, int16_t *block, int stride)
dest_unligned_store(dest);\
}
-static void h264_idct8_add_altivec(uint8_t *dst, int16_t *dct, int stride)
+static void h264_idct8_add_altivec(uint8_t *dst, int16_t *dct, ptrdiff_t stride)
{
vec_s16 s0, s1, s2, s3, s4, s5, s6, s7;
vec_s16 d0, d1, d2, d3, d4, d5, d6, d7;
@@ -266,7 +266,7 @@ static void h264_idct8_add_altivec(uint8_t *dst, int16_t *dct, int stride)
#else
#define DST_LD vec_vsx_ld
#endif
-static av_always_inline void h264_idct_dc_add_internal(uint8_t *dst, int16_t *block, int stride, int size)
+static av_always_inline void h264_idct_dc_add_internal(uint8_t *dst, int16_t *block, ptrdiff_t stride, int size)
{
vec_s16 dc16;
vec_u8 dcplus, dcminus, v0, v1, v2, v3, aligner;
@@ -316,18 +316,18 @@ static av_always_inline void h264_idct_dc_add_internal(uint8_t *dst, int16_t *bl
}
}
-static void h264_idct_dc_add_altivec(uint8_t *dst, int16_t *block, int stride)
+static void h264_idct_dc_add_altivec(uint8_t *dst, int16_t *block, ptrdiff_t stride)
{
h264_idct_dc_add_internal(dst, block, stride, 4);
}
-static void h264_idct8_dc_add_altivec(uint8_t *dst, int16_t *block, int stride)
+static void h264_idct8_dc_add_altivec(uint8_t *dst, int16_t *block, ptrdiff_t stride)
{
h264_idct_dc_add_internal(dst, block, stride, 8);
}
static void h264_idct_add16_altivec(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8])
{
int i;
@@ -341,7 +341,7 @@ static void h264_idct_add16_altivec(uint8_t *dst, const int *block_offset,
}
static void h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8])
{
int i;
@@ -352,7 +352,7 @@ static void h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offset,
}
static void h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[5 * 8])
{
int i;
@@ -366,7 +366,7 @@ static void h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset,
}
static void h264_idct_add8_altivec(uint8_t **dest, const int *block_offset,
- int16_t *block, int stride,
+ int16_t *block, ptrdiff_t stride,
const uint8_t nnzc[15 * 8])
{
int i, j;
@@ -653,7 +653,7 @@ static void h264_h_loop_filter_luma_altivec(uint8_t *pix, ptrdiff_t stride, int
}
static av_always_inline
-void weight_h264_W_altivec(uint8_t *block, int stride, int height,
+void weight_h264_W_altivec(uint8_t *block, ptrdiff_t stride, int height,
int log2_denom, int weight, int offset, int w)
{
int y, aligned;
@@ -702,7 +702,7 @@ void weight_h264_W_altivec(uint8_t *block, int stride, int height,
}
static av_always_inline
-void biweight_h264_W_altivec(uint8_t *dst, uint8_t *src, int stride, int height,
+void biweight_h264_W_altivec(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int height,
int log2_denom, int weightd, int weights, int offset, int w)
{
int y, dst_aligned, src_aligned;
diff --git a/libavcodec/riscv/h264dsp_init.c b/libavcodec/riscv/h264dsp_init.c
index 5efec9eb5e..2f6b1c38af 100644
--- a/libavcodec/riscv/h264dsp_init.c
+++ b/libavcodec/riscv/h264dsp_init.c
@@ -62,24 +62,24 @@ void ff_h264_h_loop_filter_chroma_mbaff_intra_8_rvv(uint8_t *pix,
int alpha, int beta);
#define IDCT_DEPTH(depth) \
-void ff_h264_idct_add_##depth##_rvv(uint8_t *d, int16_t *s, int stride); \
-void ff_h264_idct8_add_##depth##_rvv(uint8_t *d, int16_t *s, int stride); \
-void ff_h264_idct4_dc_add_##depth##_rvv(uint8_t *, int16_t *, int); \
-void ff_h264_idct8_dc_add_##depth##_rvv(uint8_t *, int16_t *, int); \
+void ff_h264_idct_add_##depth##_rvv(uint8_t *d, int16_t *s, ptrdiff_t stride); \
+void ff_h264_idct8_add_##depth##_rvv(uint8_t *d, int16_t *s, ptrdiff_t stride); \
+void ff_h264_idct4_dc_add_##depth##_rvv(uint8_t *, int16_t *, ptrdiff_t); \
+void ff_h264_idct8_dc_add_##depth##_rvv(uint8_t *, int16_t *, ptrdiff_t); \
void ff_h264_idct_add16_##depth##_rvv(uint8_t *d, const int *soffset, \
- int16_t *s, int stride, \
+ int16_t *s, ptrdiff_t stride, \
const uint8_t nnzc[5 * 8]); \
void ff_h264_idct_add16intra_##depth##_rvv(uint8_t *d, const int *soffset, \
- int16_t *s, int stride, \
+ int16_t *s, ptrdiff_t stride, \
const uint8_t nnzc[5 * 8]); \
void ff_h264_idct8_add4_##depth##_rvv(uint8_t *d, const int *soffset, \
- int16_t *s, int stride, \
+ int16_t *s, ptrdiff_t stride, \
const uint8_t nnzc[5 * 8]); \
void ff_h264_idct4_add8_##depth##_rvv(uint8_t **d, const int *soffset, \
- int16_t *s, int stride, \
+ int16_t *s, ptrdiff_t stride, \
const uint8_t nnzc[5 * 8]); \
void ff_h264_idct4_add8_422_##depth##_rvv(uint8_t **d, const int *soffset, \
- int16_t *s, int stride, \
+ int16_t *s, ptrdiff_t stride, \
const uint8_t nnzc[5 * 8]); \
void ff_h264_luma_dc_dequant_idct_##depth##_rvv(int16_t *d, int16_t *s, int q);
@@ -90,10 +90,10 @@ IDCT_DEPTH(12)
IDCT_DEPTH(14)
#undef IDCT_DEPTH
-void ff_h264_add_pixels8_8_rvv(uint8_t *dst, int16_t *block, int stride);
-void ff_h264_add_pixels4_8_rvv(uint8_t *dst, int16_t *block, int stride);
-void ff_h264_add_pixels8_16_rvv(uint8_t *dst, int16_t *block, int stride);
-void ff_h264_add_pixels4_16_rvv(uint8_t *dst, int16_t *block, int stride);
+void ff_h264_add_pixels8_8_rvv(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+void ff_h264_add_pixels4_8_rvv(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+void ff_h264_add_pixels8_16_rvv(uint8_t *dst, int16_t *block, ptrdiff_t stride);
+void ff_h264_add_pixels4_16_rvv(uint8_t *dst, int16_t *block, ptrdiff_t stride);
extern int ff_startcode_find_candidate_rvb(const uint8_t *, int);
extern int ff_startcode_find_candidate_rvv(const uint8_t *, int);
diff --git a/libavcodec/x86/h264_idct.asm b/libavcodec/x86/h264_idct.asm
index 7f917a4424..1d4c9729fa 100644
--- a/libavcodec/x86/h264_idct.asm
+++ b/libavcodec/x86/h264_idct.asm
@@ -225,9 +225,8 @@ SECTION .text
%endmacro
INIT_XMM sse2
-; void ff_h264_idct8_add_8_sse2(uint8_t *dst, int16_t *block, int stride)
+; void ff_h264_idct8_add_8_sse2(uint8_t *dst, int16_t *block, ptrdiff_t stride)
cglobal h264_idct8_add_8, 3, 4, 10
- movsxdifnidn r2, r2d
IDCT8_ADD_SSE r0, r1, r2, r3
RET
@@ -264,9 +263,8 @@ cglobal h264_idct8_add_8, 3, 4, 10
INIT_MMX mmxext
%if ARCH_X86_64
-; void ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride)
+; void ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, ptrdiff_t stride)
cglobal h264_idct8_dc_add_8, 3, 4, 0
- movsxd r2, r2d
movsx r3, word [r1]
mov dword [r1], 0
DC_ADD_MMXEXT_INIT r3, r2
@@ -275,7 +273,7 @@ cglobal h264_idct8_dc_add_8, 3, 4, 0
DC_ADD_MMXEXT_OP mova, r0, r2, r3
RET
%else
-; void ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride)
+; void ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, ptrdiff_t stride)
cglobal h264_idct8_dc_add_8, 2, 3, 0
movsx r2, word [r1]
mov dword [r1], 0
@@ -289,10 +287,9 @@ cglobal h264_idct8_dc_add_8, 2, 3, 0
INIT_XMM sse2
; void ff_h264_idct8_add4_8_sse2(uint8_t *dst, const int *block_offset,
-; int16_t *block, int stride,
+; int16_t *block, ptrdiff_t stride,
; const uint8_t nnzc[6 * 8])
cglobal h264_idct8_add4_8, 5, 8 + npicregs, 10, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
- movsxdifnidn r3, r3d
xor r5, r5
%if PIC
lea picregq, [scan8_mem]
@@ -345,7 +342,6 @@ INIT_XMM cpuname
INIT_MMX mmx
cglobal h264_idct_add8_422_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
; dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
- movsxdifnidn r3, r3d
%if PIC
lea picregq, [scan8_mem]
%endif
@@ -459,10 +455,9 @@ h264_add8x4_idct_sse2:
%endmacro
; void ff_h264_idct_add16_8_sse2(uint8_t *dst, const int *block_offset,
-; int16_t *block, int stride,
+; int16_t *block, ptrdiff_t stride,
; const uint8_t nnzc[6 * 8])
cglobal h264_idct_add16_8, 5, 5 + ARCH_X86_64, 8
- movsxdifnidn r3, r3d
%if ARCH_X86_64
mov r5, r0
%endif
@@ -507,10 +502,9 @@ RET
%endmacro
; void ff_h264_idct_add16intra_8_sse2(uint8_t *dst, const int *block_offset,
-; int16_t *block, int stride,
+; int16_t *block, ptrdiff_t stride,
; const uint8_t nnzc[6 * 8])
cglobal h264_idct_add16intra_8, 5, 7 + ARCH_X86_64, 8
- movsxdifnidn r3, r3d
%if ARCH_X86_64
mov r7, r0
%endif
@@ -559,10 +553,9 @@ RET
%endmacro
; void ff_h264_idct_add8_8_sse2(uint8_t **dest, const int *block_offset,
-; int16_t *block, int stride,
+; int16_t *block, ptrdiff_t stride,
; const uint8_t nnzc[6 * 8])
cglobal h264_idct_add8_8, 5, 7 + ARCH_X86_64, 8
- movsxdifnidn r3, r3d
add r2, 512
%if ARCH_X86_64
mov r7, r0
@@ -742,12 +735,10 @@ cglobal h264_luma_dc_dequant_idct, 3, 4, 6
INIT_XMM %1
cglobal h264_idct_add_8, 3, 3, 8, dst_, block_, stride_
- movsxdifnidn stride_q, stride_d
IDCT4_ADD dst_q, block_q, stride_q
RET
cglobal h264_idct_dc_add_8, 3, 4, 6, dst_, block_, stride_
- movsxdifnidn stride_q, stride_d
movsx r3d, word [block_q]
mov dword [block_q], 0
DC_ADD_INIT r3
diff --git a/libavcodec/x86/h264_idct_10bit.asm b/libavcodec/x86/h264_idct_10bit.asm
index b990db7121..741b79d044 100644
--- a/libavcodec/x86/h264_idct_10bit.asm
+++ b/libavcodec/x86/h264_idct_10bit.asm
@@ -31,7 +31,7 @@ cextern pw_1023
cextern pd_32
;-----------------------------------------------------------------------------
-; void ff_h264_idct_add_10(pixel *dst, int16_t *block, int stride)
+; void ff_h264_idct_add_10(pixel *dst, int16_t *block, ptrdiff_t stride)
;-----------------------------------------------------------------------------
%macro STORE_DIFFx2 6
psrad %1, 6
@@ -76,7 +76,6 @@ cextern pd_32
%macro IDCT_ADD_10 0
cglobal h264_idct_add_10, 3,3
- movsxdifnidn r2, r2d
IDCT4_ADD_10 r0, r1, r2
RET
%endmacro
@@ -90,7 +89,7 @@ IDCT_ADD_10
;-----------------------------------------------------------------------------
; void ff_h264_idct_add16_10(pixel *dst, const int *block_offset,
-; int16_t *block, int stride,
+; int16_t *block, ptrdiff_t stride,
; const uint8_t nnzc[6*8])
;-----------------------------------------------------------------------------
;;;;;;; NO FATE SAMPLES TRIGGER THIS
@@ -138,7 +137,6 @@ ADD4x4IDCT
%macro IDCT_ADD16_10 0
cglobal h264_idct_add16_10, 5,6
- movsxdifnidn r3, r3d
ADD16_OP 0, 4+1*8
ADD16_OP 1, 5+1*8
ADD16_OP 2, 4+2*8
@@ -166,7 +164,7 @@ IDCT_ADD16_10
%endif
;-----------------------------------------------------------------------------
-; void ff_h264_idct_dc_add_10(pixel *dst, int16_t *block, int stride)
+; void ff_h264_idct_dc_add_10(pixel *dst, int16_t *block, ptrdiff_t stride)
;-----------------------------------------------------------------------------
%macro IDCT_DC_ADD_OP_10 3
pxor m5, m5
@@ -197,7 +195,6 @@ IDCT_ADD16_10
INIT_MMX mmxext
cglobal h264_idct_dc_add_10,3,3
- movsxdifnidn r2, r2d
movd m0, [r1]
mov dword [r1], 0
paddd m0, [pd_32]
@@ -209,11 +206,10 @@ cglobal h264_idct_dc_add_10,3,3
RET
;-----------------------------------------------------------------------------
-; void ff_h264_idct8_dc_add_10(pixel *dst, int16_t *block, int stride)
+; void ff_h264_idct8_dc_add_10(pixel *dst, int16_t *block, ptrdiff_t stride)
;-----------------------------------------------------------------------------
%macro IDCT8_DC_ADD 0
cglobal h264_idct8_dc_add_10,3,4,7
- movsxdifnidn r2, r2d
movd m0, [r1]
mov dword[r1], 0
paddd m0, [pd_32]
@@ -236,7 +232,7 @@ IDCT8_DC_ADD
;-----------------------------------------------------------------------------
; void ff_h264_idct_add16intra_10(pixel *dst, const int *block_offset,
-; int16_t *block, int stride,
+; int16_t *block, ptrdiff_t stride,
; const uint8_t nnzc[6*8])
;-----------------------------------------------------------------------------
%macro AC 1
@@ -283,7 +279,6 @@ idct_dc_add %+ SUFFIX:
ret
cglobal h264_idct_add16intra_10,5,7,8
- movsxdifnidn r3, r3d
ADD16_OP_INTRA 0, 4+1*8
ADD16_OP_INTRA 2, 4+2*8
ADD16_OP_INTRA 4, 6+1*8
@@ -313,12 +308,11 @@ IDCT_ADD16INTRA_10
%assign last_block 36
;-----------------------------------------------------------------------------
; void ff_h264_idct_add8_10(pixel **dst, const int *block_offset,
-; int16_t *block, int stride,
+; int16_t *block, ptrdiff_t stride,
; const uint8_t nnzc[6*8])
;-----------------------------------------------------------------------------
%macro IDCT_ADD8 0
cglobal h264_idct_add8_10,5,8,7
- movsxdifnidn r3, r3d
%if ARCH_X86_64
mov r7, r0
%endif
@@ -352,7 +346,7 @@ IDCT_ADD8
;-----------------------------------------------------------------------------
; void ff_h264_idct_add8_422_10(pixel **dst, const int *block_offset,
-; int16_t *block, int stride,
+; int16_t *block, ptrdiff_t stride,
; const uint8_t nnzc[6*8])
;-----------------------------------------------------------------------------
%assign last_block 44
@@ -360,7 +354,6 @@ IDCT_ADD8
%macro IDCT_ADD8_422 0
cglobal h264_idct_add8_422_10, 5, 8, 7
- movsxdifnidn r3, r3d
%if ARCH_X86_64
mov r7, r0
%endif
@@ -404,7 +397,7 @@ IDCT_ADD8_422
%endif
;-----------------------------------------------------------------------------
-; void ff_h264_idct8_add_10(pixel *dst, int16_t *block, int stride)
+; void ff_h264_idct8_add_10(pixel *dst, int16_t *block, ptrdiff_t stride)
;-----------------------------------------------------------------------------
%macro IDCT8_1D 2
SWAP 0, 1
@@ -488,7 +481,7 @@ IDCT_ADD8_422
%endif
%endmacro
-; %1=uint8_t *dst, %2=int16_t *block, %3=int stride
+; %1=uint8_t *dst, %2=int16_t *block, %3=ptrdiff_t stride
%macro IDCT8_ADD_SSE_END 3
IDCT8_1D_FULL %2
mova [%2 ], m6
@@ -508,7 +501,6 @@ IDCT_ADD8_422
%macro IDCT8_ADD 0
cglobal h264_idct8_add_10, 3,4,16
- movsxdifnidn r2, r2d
%if UNIX64 == 0
%assign pad 16-gprsize-(stack_offset&15)
sub rsp, pad
@@ -615,7 +607,7 @@ IDCT8_ADD
;-----------------------------------------------------------------------------
; void ff_h264_idct8_add4_10(pixel **dst, const int *block_offset,
-; int16_t *block, int stride,
+; int16_t *block, ptrdiff_t stride,
; const uint8_t nnzc[6*8])
;-----------------------------------------------------------------------------
;;;;;;; NO FATE SAMPLES TRIGGER THIS
@@ -633,7 +625,6 @@ IDCT8_ADD
%macro IDCT8_ADD4 0
cglobal h264_idct8_add4_10, 0,7,16
- movsxdifnidn r3, r3d
%assign pad 16-gprsize-(stack_offset&15)
SUB rsp, pad
mov r5, r0mp
diff --git a/libavcodec/x86/h264dsp_init.c b/libavcodec/x86/h264dsp_init.c
index f617078d15..d853219fb1 100644
--- a/libavcodec/x86/h264dsp_init.c
+++ b/libavcodec/x86/h264dsp_init.c
@@ -28,7 +28,7 @@
#define IDCT_ADD_FUNC(NUM, DEPTH, OPT) \
void ff_h264_idct ## NUM ## _add_ ## DEPTH ## _ ## OPT(uint8_t *dst, \
int16_t *block, \
- int stride);
+ ptrdiff_t stride);
IDCT_ADD_FUNC(, 8, sse2)
IDCT_ADD_FUNC(, 8, avx)
@@ -48,7 +48,7 @@ IDCT_ADD_FUNC(8, 10, avx)
#define IDCT_ADD_REP_FUNC(NUM, REP, DEPTH, OPT) \
void ff_h264_idct ## NUM ## _add ## REP ## _ ## DEPTH ## _ ## OPT \
(uint8_t *dst, const int *block_offset, \
- int16_t *block, int stride, const uint8_t nnzc[5 * 8]);
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[5 * 8]);
IDCT_ADD_REP_FUNC(8, 4, 8, sse2)
IDCT_ADD_REP_FUNC(8, 4, 10, sse2)
@@ -64,7 +64,7 @@ IDCT_ADD_REP_FUNC(, 16intra, 10, avx)
#define IDCT_ADD_REP_FUNC2(NUM, REP, DEPTH, OPT) \
void ff_h264_idct ## NUM ## _add ## REP ## _ ## DEPTH ## _ ## OPT \
(uint8_t **dst, const int *block_offset, \
- int16_t *block, int stride, const uint8_t nnzc[15 * 8]);
+ int16_t *block, ptrdiff_t stride, const uint8_t nnzc[15 * 8]);
IDCT_ADD_REP_FUNC2(, 8, 8, sse2)
IDCT_ADD_REP_FUNC2(, 8, 10, sse2)
diff --git a/tests/checkasm/h264dsp.c b/tests/checkasm/h264dsp.c
index 5a5a553901..9fbb24d2d3 100644
--- a/tests/checkasm/h264dsp.c
+++ b/tests/checkasm/h264dsp.c
@@ -184,7 +184,7 @@ static void check_idct(void)
LOCAL_ALIGNED_16(int16_t, subcoef1, [8 * 8 * 2]);
H264DSPContext h;
int bit_depth, sz, align, dc, i;
- declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, int16_t *block, int stride);
+ declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, int16_t *block, ptrdiff_t stride);
for (i = 0; i < FF_ARRAY_ELEMS(depths); i++) {
bit_depth = depths[i];
@@ -192,7 +192,7 @@ static void check_idct(void)
for (dc = 0; dc <= 2; dc++) {
for (sz = 4; sz <= 8; sz += 4) {
- void (*idct)(uint8_t *, int16_t *, int) = NULL;
+ void (*idct)(uint8_t *, int16_t *, ptrdiff_t) = NULL;
const char fmts[3][28] = {
"idct%d_add_%dbpp", "idct%d_dc_add_%dbpp",
"add_pixels%d_%dbpp",
@@ -250,12 +250,12 @@ static void check_idct_multiple(void)
LOCAL_ALIGNED_16(uint8_t, nnzc, [15 * 8]);
H264DSPContext h;
int bit_depth, i, y, func;
- declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]);
+ declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, const int *block_offset, int16_t *block, ptrdiff_t stride, const uint8_t nnzc[15*8]);
for (bit_depth = 8; bit_depth <= 10; bit_depth++) {
ff_h264dsp_init(&h, bit_depth, 1);
for (func = 0; func < 3; func++) {
- void (*idct)(uint8_t *, const int *, int16_t *, int, const uint8_t[]) = NULL;
+ void (*idct)(uint8_t *, const int *, int16_t *, ptrdiff_t, const uint8_t[]) = NULL;
const char *name;
int sz = 4, intra = 0;
int block_offset[16] = { 0 };
--
2.52.0
2
1
Hi everyone
Lots of new stuff :)
* Fairy supports github now, she is monitoring my repositories on github too
* Her UI has evolved and since today supports rendering everyones messages not just the one proposed to be sent
* public repo is 167 commits behind this, i know thats lame, i have to clean things up and push
Also if you dont want fairy to review, just tell her
heres an example that worked:
And if you see her do something annoying, tell me about it and ill try to adjust her prompt
| state skipped llm skip reviewed 2026-08-06 19:42 (0h ago)
│ reason: LLM skip: After our latest review, the author confirmed they will update the patchset and the maintainer explicitly said to wait for those fixes. No new commit has been pushed since then,
│ so another reply would add noise while the PR is waiting on the author.
...
│ @toots - will you be updating the patchset on account of the @Forgejo_Fairy findings?
│
│ toots comment 2026-08-06 16:48 (3h ago)
│ @GyanD wrote in https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23839#issuecomment-54997:
│
│ ▌ @toots - will you be updating the patchset on account of the @Forgejo_Fairy findings?
│
│ Absolutely just didn't have time yet. Any feedback you want to send before I do so?
│ GyanD comment 2026-08-06 18:53 (1h ago)
│ @toots - I'll wait for you to address the FF issues.
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
It is a danger to trust the dream we wish for rather than
the science we have, -- Dr. Kenneth Brown
1
1
This series adds an AVX2 implementation of the VVC planar intra
prediction kernel, which currently has no SIMD implementation on any
architecture. Only 8-bit is implemented here; the 10 and 12-bit paths
still use the C reference and can be added in a follow-up.
Patch 1 adds a checkasm test so the second patch can be verified. The
test iterates 8, 10 and 12 bit, so it will also cover the higher depths
once SIMD for them is added.
Patch 2 adds the 8-bit kernel and wires up x86 dispatch.
Tested on AMD Ryzen 7 5825U:
- checkasm passes: the 8-bit AVX2 kernel matches the C reference
- fate-vvc passes, unchanged from before the series
- framemd5 output is identical with and without -cpuflags 0
Gudikandula Samith (2):
tests/checkasm: add vvc_intra test for pred_planar
lavc/vvc: add AVX2 planar intra prediction
libavcodec/x86/vvc/Makefile | 1 +
libavcodec/x86/vvc/dsp_init.c | 13 ++
libavcodec/x86/vvc/intra.asm | 224 ++++++++++++++++++++++++++++++++++
tests/checkasm/Makefile | 2 +-
tests/checkasm/checkasm.c | 7 +-
tests/checkasm/checkasm.h | 1 +
tests/checkasm/vvc_intra.c | 87 +++++++++++++
7 files changed, 331 insertions(+), 4 deletions(-)
create mode 100644 libavcodec/x86/vvc/intra.asm
create mode 100644 tests/checkasm/vvc_intra.c
--
2.53.0
3
9
09 Aug '26
PR #24063 opened by Théo Valette (theovalette)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24063
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24063.patch
The PNG parser returns a complete image when it reaches the IEND chunk and its
CRC. If bytes remain, it buffers them while looking for another PNG signature.
At EOF, the generic parser flush returns that signature-less buffer as a second
packet, which the decoder rejects as an invalid PNG. The same data also prefixes
the next image when the png_pipe demuxer loops.
Track whether the parser has completed an image. After that point, discard
signature-less trailing bytes at EOF and skip interstitial bytes before a
subsequent valid PNG or MNG signature. Preserve the existing EOF flush for an
invalid or truncated first packet.
Regression coverage directly exercises trailing data, interstitial data, a
signature split across parser calls, and the existing invalid-input EOF flush.
Tests performed:
- `make -j$(nproc) fate-png-parser`
- `make -j$(nproc) fate-libavcodec` with the documented minimal configuration
- `make -j$(nproc) fate` with the documented minimal configuration
- `make -j$(nproc) fate-png-parser` with `--toolchain=gcc-asan`
- Manual ffprobe and decode checks with the issue attachment
- Two-frame `-loop 1` and `-stream_loop 1` checks with the issue attachment
- `git diff --check`
- `tools/patcheck` on the generated format-patch
The configured `make fate` run warned that it covered only the enabled subset
because no external `SAMPLES` directory was specified. The existing
sample-based `fate-pngparser` test was therefore unavailable. The new regression
test is self-contained and passed in both the normal and sanitizer builds.
Fixes #23103.
Sample: https://code.ffmpeg.org/attachments/8ab0ff3e-04d1-49fa-90ec-a9bdfc6d4354
From 497a1507f43e1ed47e625d60935f0573c67a0408 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Th=C3=A9o=20Valette?=
<315040668+theovalette(a)users.noreply.github.com>
Date: Sun, 9 Aug 2026 18:48:10 +0200
Subject: [PATCH] avcodec/png_parser: Ignore trailing data after IEND
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
After returning an image through its IEND CRC, the parser buffers the
following bytes while searching for another PNG signature. The generic EOF
flush then exposes signature-less trailing bytes as another packet.
Discard such data after a completed frame, while preserving the EOF flush for
an invalid first packet. Also skip interstitial data before a subsequent valid
signature so image-pipe looping remains valid.
Fixes #23103.
Signed-off-by: Théo Valette <315040668+theovalette(a)users.noreply.github.com>
---
libavcodec/Makefile | 1 +
libavcodec/png_parser.c | 35 +++++++-
libavcodec/tests/png_parser.c | 165 ++++++++++++++++++++++++++++++++++
tests/fate/libavcodec.mak | 5 ++
4 files changed, 204 insertions(+), 2 deletions(-)
create mode 100644 libavcodec/tests/png_parser.c
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index e464811af6..baf6d8f688 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1392,6 +1392,7 @@ TESTPROGS-$(CONFIG_IDCTDSP) += dct
TESTPROGS-$(CONFIG_DXV_ENCODER) += hashtable
TESTPROGS-$(CONFIG_MJPEG_ENCODER) += mjpegenc_huffman
TESTPROGS-$(CONFIG_MPEGVIDEO) += mpeg12framerate
+TESTPROGS-$(CONFIG_PNG_PARSER) += png_parser
TESTPROGS-$(CONFIG_H264_METADATA_BSF) += h264_levels
TESTPROGS-$(CONFIG_HEVC_METADATA_BSF) += h265_levels
TESTPROGS-$(CONFIG_RANGECODER) += rangecoder
diff --git a/libavcodec/png_parser.c b/libavcodec/png_parser.c
index fbeae1103b..7a1ac5fdad 100644
--- a/libavcodec/png_parser.c
+++ b/libavcodec/png_parser.c
@@ -33,6 +33,7 @@ typedef struct PNGParseContext {
uint32_t chunk_pos; ///< position inside current chunk
uint32_t chunk_length; ///< length of the current chunk
uint32_t remaining_size; ///< remaining size of the current chunk
+ int parsed_frame;
} PNGParseContext;
static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx,
@@ -41,6 +42,7 @@ static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx,
{
PNGParseContext *ppc = s->priv_data;
int next = END_NOT_FOUND;
+ int skipped = 0;
int i = 0;
s->pict_type = AV_PICTURE_TYPE_NONE;
@@ -48,6 +50,13 @@ static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx,
*poutbuf_size = 0;
*poutbuf = NULL;
+ /* Do not return signature-less trailing data as another frame. */
+ if (!buf_size && ppc->parsed_frame && !ppc->pc.frame_start_found) {
+ ppc->pc.index = 0;
+ ppc->pc.state64 = 0;
+ return 0;
+ }
+
if (!ppc->pc.frame_start_found) {
uint64_t state64 = ppc->pc.state64;
for (; i < buf_size; i++) {
@@ -55,6 +64,24 @@ static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx,
if (state64 == PNGSIG || state64 == MNGSIG) {
i++;
ppc->pc.frame_start_found = 1;
+ if (ppc->parsed_frame) {
+ /* Drop data between the previous frame and this one. */
+ if (i >= 8) {
+ skipped = i - 8;
+ ppc->pc.index = 0;
+ buf += skipped;
+ buf_size -= skipped;
+ i = 8;
+ } else {
+ int signature_size = 8 - i;
+ int signature_pos = ppc->pc.index - signature_size;
+
+ memmove(ppc->pc.buffer,
+ ppc->pc.buffer + signature_pos,
+ signature_size);
+ ppc->pc.index = signature_size;
+ }
+ }
break;
}
}
@@ -102,13 +129,17 @@ static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx,
flush:
if (ff_combine_frame(&ppc->pc, next, &buf, &buf_size) < 0)
- return buf_size;
+ return skipped + buf_size;
ppc->chunk_pos = ppc->pc.frame_start_found = 0;
+ if (next != END_NOT_FOUND) {
+ ppc->parsed_frame = 1;
+ ppc->pc.state64 = 0;
+ }
*poutbuf = buf;
*poutbuf_size = buf_size;
- return next;
+ return skipped + next;
}
const FFCodecParser ff_png_parser = {
diff --git a/libavcodec/tests/png_parser.c b/libavcodec/tests/png_parser.c
new file mode 100644
index 0000000000..e2cfeea0c2
--- /dev/null
+++ b/libavcodec/tests/png_parser.c
@@ -0,0 +1,165 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libavcodec/avcodec.h"
+
+#define PNG_SIZE 20
+
+static const uint8_t png[PNG_SIZE + AV_INPUT_BUFFER_PADDING_SIZE] = {
+ 0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a,
+ 0, 0, 0, 0, 'I', 'E', 'N', 'D', 0, 0, 0, 0,
+};
+
+static int parse(AVCodecParserContext *parser, AVCodecContext *avctx,
+ const uint8_t *buf, int size,
+ int expected_consumed, int expected_size,
+ const uint8_t *expected)
+{
+ uint8_t *out;
+ int out_size;
+ int consumed = av_parser_parse2(parser, avctx, &out, &out_size, buf, size,
+ AV_NOPTS_VALUE, AV_NOPTS_VALUE, -1);
+
+ if (consumed != expected_consumed || out_size != expected_size ||
+ expected_size && memcmp(out, expected, expected_size)) {
+ fprintf(stderr, "consumed %d (expected %d), output %d "
+ "(expected %d)\n", consumed, expected_consumed,
+ out_size, expected_size);
+ return 1;
+ }
+ return 0;
+}
+
+static int test_trailing_data(void)
+{
+ static const uint8_t input[PNG_SIZE + 3 + AV_INPUT_BUFFER_PADDING_SIZE] = {
+ 0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a,
+ 0, 0, 0, 0, 'I', 'E', 'N', 'D', 0, 0, 0, 0,
+ 1, 2, 3,
+ };
+ AVCodecParserContext *parser = av_parser_init(AV_CODEC_ID_PNG);
+ AVCodecContext *avctx = avcodec_alloc_context3(NULL);
+ int ret;
+
+ if (!parser || !avctx) {
+ av_parser_close(parser);
+ avcodec_free_context(&avctx);
+ return 1;
+ }
+ avctx->codec_id = AV_CODEC_ID_PNG;
+
+ ret = parse(parser, avctx, input, PNG_SIZE + 3,
+ PNG_SIZE, PNG_SIZE, png);
+ ret |= parse(parser, avctx, input + PNG_SIZE, 3, 3, 0, NULL);
+ ret |= parse(parser, avctx, NULL, 0, 0, 0, NULL);
+ av_parser_close(parser);
+ avcodec_free_context(&avctx);
+ return ret;
+}
+
+static int test_interstitial_data(void)
+{
+ static const uint8_t input[2 * PNG_SIZE + 3 +
+ AV_INPUT_BUFFER_PADDING_SIZE] = {
+ 0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a,
+ 0, 0, 0, 0, 'I', 'E', 'N', 'D', 0, 0, 0, 0,
+ 1, 2, 3,
+ 0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a,
+ 0, 0, 0, 0, 'I', 'E', 'N', 'D', 0, 0, 0, 0,
+ };
+ AVCodecParserContext *parser = av_parser_init(AV_CODEC_ID_PNG);
+ AVCodecContext *avctx = avcodec_alloc_context3(NULL);
+ int ret;
+
+ if (!parser || !avctx) {
+ av_parser_close(parser);
+ avcodec_free_context(&avctx);
+ return 1;
+ }
+ avctx->codec_id = AV_CODEC_ID_PNG;
+
+ ret = parse(parser, avctx, input, 2 * PNG_SIZE + 3,
+ PNG_SIZE, PNG_SIZE, png);
+ ret |= parse(parser, avctx, input + PNG_SIZE, PNG_SIZE + 3,
+ PNG_SIZE + 3, PNG_SIZE, png);
+ ret |= parse(parser, avctx, NULL, 0, 0, 0, NULL);
+ av_parser_close(parser);
+ avcodec_free_context(&avctx);
+ return ret;
+}
+
+static int test_split_signature(void)
+{
+ static const uint8_t prefix[5 + AV_INPUT_BUFFER_PADDING_SIZE] = {
+ 1, 2, 3, 0x89, 'P',
+ };
+ AVCodecParserContext *parser = av_parser_init(AV_CODEC_ID_PNG);
+ AVCodecContext *avctx = avcodec_alloc_context3(NULL);
+ int ret;
+
+ if (!parser || !avctx) {
+ av_parser_close(parser);
+ avcodec_free_context(&avctx);
+ return 1;
+ }
+ avctx->codec_id = AV_CODEC_ID_PNG;
+
+ ret = parse(parser, avctx, png, PNG_SIZE, PNG_SIZE, PNG_SIZE, png);
+ ret |= parse(parser, avctx, prefix, 5, 5, 0, NULL);
+ ret |= parse(parser, avctx, png + 2, PNG_SIZE - 2,
+ PNG_SIZE - 2, PNG_SIZE, png);
+ ret |= parse(parser, avctx, NULL, 0, 0, 0, NULL);
+ av_parser_close(parser);
+ avcodec_free_context(&avctx);
+ return ret;
+}
+
+static int test_existing_eof_flush(void)
+{
+ static const uint8_t invalid[3 + AV_INPUT_BUFFER_PADDING_SIZE] = {
+ 1, 2, 3,
+ };
+ AVCodecParserContext *parser = av_parser_init(AV_CODEC_ID_PNG);
+ AVCodecContext *avctx = avcodec_alloc_context3(NULL);
+ int ret;
+
+ if (!parser || !avctx) {
+ av_parser_close(parser);
+ avcodec_free_context(&avctx);
+ return 1;
+ }
+ avctx->codec_id = AV_CODEC_ID_PNG;
+
+ ret = parse(parser, avctx, invalid, 3, 3, 0, NULL);
+ ret |= parse(parser, avctx, NULL, 0, 0, 3, invalid);
+ av_parser_close(parser);
+ avcodec_free_context(&avctx);
+ return ret;
+}
+
+int main(void)
+{
+ return test_trailing_data() ||
+ test_interstitial_data() ||
+ test_split_signature() ||
+ test_existing_eof_flush();
+}
diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak
index e2d616e307..530fcb9e30 100644
--- a/tests/fate/libavcodec.mak
+++ b/tests/fate/libavcodec.mak
@@ -91,6 +91,11 @@ fate-rangecoder: libavcodec/tests/rangecoder$(EXESUF)
fate-rangecoder: CMD = run libavcodec/tests/rangecoder$(EXESUF)
fate-rangecoder: CMP = null
+FATE_LIBAVCODEC-$(CONFIG_PNG_PARSER) += fate-png-parser
+fate-png-parser: libavcodec/tests/png_parser$(EXESUF)
+fate-png-parser: CMD = run libavcodec/tests/png_parser$(EXESUF)
+fate-png-parser: CMP = null
+
FATE_LIBAVCODEC-yes += fate-mathops
fate-mathops: libavcodec/tests/mathops$(EXESUF)
fate-mathops: CMD = run libavcodec/tests/mathops$(EXESUF)
--
2.52.0
1
0
09 Aug '26
PR #24062 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24062
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24062.patch
Fairy took this literally
See: #23985
Signed-off-by: Michael Niedermayer <michael(a)niedermayer.cc>
From 01f0a32d54504e6bc68549cbcdf9bc12fa3abf59 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <michael(a)niedermayer.cc>
Date: Sun, 9 Aug 2026 17:09:01 +0200
Subject: [PATCH] doc/developer.texi: More precisse wording for Robustness
Fairy takes this literally
See: #23985
Signed-off-by: Michael Niedermayer <michael(a)niedermayer.cc>
---
doc/developer.texi | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/doc/developer.texi b/doc/developer.texi
index 0a0cce63f5..92ccedd381 100644
--- a/doc/developer.texi
+++ b/doc/developer.texi
@@ -411,9 +411,15 @@ The code must behave correctly under such conditions.
@subheading Robustness
The code must treat as untrusted any bytestream received from a caller or read
-from a file, network, etc. It must not misbehave when arbitrary data is sent to
-it - typically it should print an error message and return
-@code{AVERROR_INVALIDDATA} on encountering invalid input data.
+from a file, network, etc. Arbitrary input must never cause unsafe
+behavior or a security issue.
+
+Common real-world errors of common formats and codecs should be detected where practical,
+reported where appropriate, and handled to produce the best output possible,
+for example through error concealment.
+
+All errors must still be handled safely, but if they are detected,
+reporting or how they are handled is left to the implementation.
@subheading Memory allocation
The code must use the @code{av_malloc()} family of functions from
--
2.52.0
1
0
Granulate is a Video Granulator that works in the time-domain. The filter stores past frames in a FIFO buffer, and uses rectangular patches of those frames, to create grains in the current frame. The filter lets the user choose between different granulation methods and alterations of the pixels in the buffered frames
Signed-off-by: Gian Paolo Gigante <gian(a)prototoi.net>
---
Changelog | 1 +
doc/filters.texi | 62 ++++
libavfilter/version.h | 4 +-
libavfilter/vf_granulate.c | 688 ++++++++++++++++++++++++++++++++++++
tests/fate/filter-video.mak | 6 +
5 files changed, 759 insertions(+), 2 deletions(-)
create mode 100644 libavfilter/vf_granulate.c
diff --git a/Changelog b/Changelog
index 38f1e10263..8338e67f49 100644
--- a/Changelog
+++ b/Changelog
@@ -10,6 +10,7 @@ version <next>:
- latticepal filter
- DVD-Audio LPCM decoder and demuxing support
- AVFoundation input device selection by unique ID and USB serial number
+- granulate filter
version 9.0:
diff --git a/doc/filters.texi b/doc/filters.texi
index 985a1615a9..b98162f537 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -15420,6 +15420,68 @@ Set upper limit for video rate of output stream, Default value is @var{25}.
This guarantee that output video frame rate will not be higher than this value.
@end table
+@section granulate
+A Time-Domain Video Granulator: granulates past frames in current frame
+
+@example
+ffmpeg -i INPUT -vf granulate=mode=3:zoom=2:offset_time=50:buffer=64:n_grains=2:ghosting=1 OUTPUT
+@end example
+
+@table @option
+
+@item mode
+Set the type of granulation @code{[0 - 3]}. Default is @code{0} @*
+0 : PIXELS Granulates rectangular blocks @*
+1 : INTERLACED_H Granulates every other line @*
+2 : INTERLACED_V Granulates every other column @*
+3 : DITHER Granulates in a noisy manner
+
+@item zoom
+Set the amount of zoom applied to the grains @code{[1 - 256]}. Default is @code{1}
+
+@item offset_time
+Set the amount of frames before the offset of the zoom is reset @code{[0 - UINT_MAX]}. Default is @code{0 : OFF}
+
+@item n_grains
+Set the number of grains per frame @code{[0 - UINT_MAX]}. Default is @code{0 : OFF}
+
+@item buffer
+Set the size of the buffer of frames (FIFO) - Each grain will be generated from a random frame @code{[1 - 8192]}. Default is @code{1}
+
+@item grain_w
+Set the width of the grains - If set to 0, each grain will have the width of the INPUT file @code{[0 - 8192]}. Default is @code{0}
+
+@item grain_h
+Set the height of the grains - If set to 0, each grain will have the height of the INPUT file @code{[0 - 8192]}. Default is @code{0}
+
+@item var_size
+Toggle random grain width and height (Each grain will have a random size between grain_w/h and 0) @code{[0 - 1]}. Default is @code{0 : OFF}
+
+@item ghosting
+Set the type of ghosting @code{[0 - 2]}. Default is @code{0} @*
+0 : NO_GHOSTING Grains have both Luma and Chroma components @*
+1 : LUMA_GHOSTING Grains have only luma component @*
+2 : CHROMA_GHOSTING Grains have only chroma component @*
+
+@item static_grains
+Toggle stable grain position @code{[0 - 1]}. Default is @code{0 : OFF}
+
+@item reset_time
+Set the number of frames before the stable position are reset @code{[0 - UINT_MAX]}. Default is @code{0 : OFF}
+
+@item delay
+Set number of frames before refreshing the delay (stable buffer offset) @code{[0 - UINT_MAX]}. Default is @code{0 : OFF}
+
+@item seed
+Set the seed for internal AVlfg - If 0, the seed will be generated randomly @code{[0 - UINT32_MAX]}. Default is @code{0}
+
+@end table
+
+@subsection Runtime Params
+
+This filter supports runtime change for specific parameters: @*
+[mode - zoom - offset_time - ghosting - delay]
+
@section grayworld
A color constancy filter that applies color correction based on the grayworld assumption
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 48abf6052f..4d8f28e512 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -31,8 +31,8 @@
#include "version_major.h"
-#define LIBAVFILTER_VERSION_MINOR 3
-#define LIBAVFILTER_VERSION_MICRO 101
+#define LIBAVFILTER_VERSION_MINOR 4
+#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
diff --git a/libavfilter/vf_granulate.c b/libavfilter/vf_granulate.c
new file mode 100644
index 0000000000..d07710dd16
--- /dev/null
+++ b/libavfilter/vf_granulate.c
@@ -0,0 +1,688 @@
+/*
+ * Copyright (c) 2026 Gian Paolo Gigante
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Time-Domain Video Granulator: Granulate past frames in current frame
+ *
+ */
+
+#include "avfilter.h"
+#include "libavutil/attributes.h"
+#include "libavutil/frame.h"
+#include "libavutil/mem.h"
+#include "libavutil/opt.h"
+#include "libavutil/lfg.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/random_seed.h"
+#include "formats.h"
+#include "video.h"
+#include "error.h"
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+
+
+typedef enum FilterMode {
+ MODE_PIXELS,
+ MODE_INTERLACED_H,
+ MODE_INTERLACED_V,
+ MODE_DITHER
+} filter_mode;
+
+typedef enum GhostingMode {
+ NO_GHOSTING,
+ LUMA_GHOSTING,
+ CHROMA_GHOSTING
+} ghosting_mode;
+
+typedef void (*copy_grain)(AVFrame *dst, const AVFrame *src, int sx, int sy, int dx, int dy,
+ int w, int h, filter_mode mode, ghosting_mode ghosting, int zoom, int var_size,
+ int PxFmt, uint8_t log2_chroma_h, uint8_t log2_chroma_w, AVLFG *lfg);
+
+typedef struct GrainPos{
+ int pos_x;
+ int pos_y;
+ int g_pos_x;
+ int g_pos_y;
+} GrainPos;
+
+typedef struct GranulateContext {
+ const AVClass *class;
+
+ int PixFmt;
+ AVLFG *lfg;
+ uint32_t seed;
+ filter_mode mode;
+ ghosting_mode ghosting;
+ unsigned int buffer_size, buffer_index, buffer_full;
+ AVFrame **fbuffer;
+ unsigned int zoom_amount, zoom_set;
+ unsigned int zoom_offset_w, zoom_offset_h;
+ unsigned int offset_time;
+ copy_grain copy_grain_fn;
+ unsigned int grain_w, grain_h;
+ int fullscreen;
+ unsigned int n_grains;
+ int static_grains;
+ GrainPos *grain_pos;
+ int grains_set;
+ unsigned int reset_time;
+ int var_size;
+ uint64_t frame_count;
+ uint8_t log2_chroma_h, log2_chroma_w;
+ unsigned int delay;
+ unsigned int delay_set;
+} GranulateContext;
+
+#define OFFSET(x) offsetof(GranulateContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+#define R AV_OPT_FLAG_RUNTIME_PARAM
+
+static const AVOption granulate_options[] = {
+ {"mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_PIXELS}, MODE_PIXELS, MODE_DITHER, FLAGS | R},
+ {"zoom", "set zoom amount", OFFSET(zoom_amount), AV_OPT_TYPE_UINT, {.i64=1}, 1, 256, FLAGS | R},
+ {"offset_time", "set number of frames befor zoom offset is reset", OFFSET(offset_time), AV_OPT_TYPE_UINT, {.i64=0}, 0, UINT_MAX, FLAGS | R},
+ {"n_grains", "number of grains per frame", OFFSET(n_grains), AV_OPT_TYPE_UINT, {.i64=0}, 0, UINT_MAX, FLAGS},
+ {"buffer", "set the size of the buffer", OFFSET(buffer_size), AV_OPT_TYPE_UINT, {.i64=1}, 1, 8192, FLAGS},
+ {"grain_w", "set the width of each grain in px", OFFSET(grain_w), AV_OPT_TYPE_UINT, {.i64=0}, 0, 8192, FLAGS},
+ {"grain_h", "set the height of each grain in px", OFFSET(grain_h), AV_OPT_TYPE_UINT, {.i64=0}, 0, 8192, FLAGS},
+ {"var_size", "toggle random grain size (grain_size as max size)", OFFSET(var_size), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
+ {"ghosting", "select type of ghosting", OFFSET(ghosting), AV_OPT_TYPE_INT, {.i64=NO_GHOSTING}, NO_GHOSTING, CHROMA_GHOSTING, FLAGS | R},
+ {"static_grains", "toggle stable grain position", OFFSET(static_grains), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
+ {"reset_time","set number of frames before grain_pos reset", OFFSET(reset_time), AV_OPT_TYPE_UINT, {.i64=0}, 0, UINT_MAX, FLAGS},
+ {"delay", "set number of frames before refresh of delay", OFFSET(delay), AV_OPT_TYPE_UINT, {.i64=0}, 0, UINT_MAX, FLAGS | R},
+ {"seed", "set seed for AVlfg", OFFSET(seed), AV_OPT_TYPE_UINT, {.i64=0}, 0, UINT32_MAX, FLAGS},
+ { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(granulate);
+
+static av_cold int init(AVFilterContext *ctx)
+{
+ int i;
+ GranulateContext *granulate_ctx = ctx->priv;
+
+ granulate_ctx->lfg = av_calloc(1, sizeof(AVLFG));
+ if (!granulate_ctx->lfg)
+ return AVERROR(ENOMEM);
+
+ if (!granulate_ctx->seed)
+ granulate_ctx->seed = av_get_random_seed();
+ av_lfg_init(granulate_ctx->lfg, granulate_ctx->seed);
+
+ if (granulate_ctx->static_grains && granulate_ctx->n_grains) {
+ granulate_ctx->grain_pos = av_calloc(granulate_ctx->n_grains, sizeof(GrainPos));
+
+ if (!granulate_ctx->grain_pos)
+ return AVERROR(ENOMEM);
+ }
+
+ granulate_ctx->fbuffer = av_calloc(granulate_ctx->buffer_size, sizeof(AVFrame *));
+
+ if (!granulate_ctx->fbuffer)
+ return AVERROR(ENOMEM);
+
+ for (i = 0; i < granulate_ctx->buffer_size; i++) {
+ granulate_ctx->fbuffer[i] = av_frame_alloc();
+
+ if (!granulate_ctx->fbuffer[i])
+ return AVERROR(ENOMEM);
+ }
+ granulate_ctx->buffer_index = 0;
+ granulate_ctx->zoom_offset_w = 0;
+ granulate_ctx->zoom_offset_h = 0;
+ granulate_ctx->frame_count = 0;
+ granulate_ctx->zoom_set = 0;
+ granulate_ctx->buffer_full = 0;
+ granulate_ctx->delay_set = 0;
+ granulate_ctx->fullscreen = 1;
+
+ return 0;
+}
+
+static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
+{
+ static const enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,
+ AV_PIX_FMT_GRAY8, AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE};
+
+ return ff_set_pixel_formats_from_list2(ctx, cfg_in, cfg_out, pix_fmts);
+}
+
+static int granulate_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
+{
+ av_log(ctx, AV_LOG_INFO, "Received command: %s=%s\n", cmd, arg);
+ return ff_filter_process_command(ctx, cmd, arg, res, res_len, flags);
+}
+
+static void copy_grain_YUV(AVFrame *dst, const AVFrame *src, int sx, int sy, int dx, int dy, int grain_w, int grain_h, filter_mode mode, ghosting_mode ghosting, int zoom, int var_size, int PxFmt, uint8_t log2_chroma_h, uint8_t log2_chroma_w, AVLFG *lfg);
+
+static void copy_grain_GRAY(AVFrame *dst, const AVFrame *src, int sx, int sy, int dx, int dy, int grain_w, int grain_h, filter_mode mode, ghosting_mode ghosting, int zoom, int var_size, int PxFmt, uint8_t log2_chroma_h, uint8_t log2_chroma_w, AVLFG *lfg);
+
+static void copy_grain_RGB(AVFrame *dst, const AVFrame *src, int sx, int sy, int dx, int dy, int grain_w, int grain_h, filter_mode mode, ghosting_mode ghosting, int zoom, int var_size, int PxFmt, uint8_t log2_chroma_h, uint8_t log2_chroma_w, AVLFG *lfg);
+
+static int config_props(AVFilterLink *inlink)
+{
+ AVFilterContext *ctx = inlink->dst;
+ GranulateContext *granulate_ctx = ctx->priv;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+
+ granulate_ctx->log2_chroma_h = desc->log2_chroma_h;
+ granulate_ctx->log2_chroma_w = desc->log2_chroma_w;
+
+ switch (inlink->format) {
+ case (AV_PIX_FMT_YUV420P):
+ granulate_ctx->PixFmt = AV_PIX_FMT_YUV420P; granulate_ctx->copy_grain_fn = copy_grain_YUV; break;
+ case (AV_PIX_FMT_YUV422P):
+ granulate_ctx->PixFmt = AV_PIX_FMT_YUV422P; granulate_ctx->copy_grain_fn = copy_grain_YUV; break;
+ case (AV_PIX_FMT_YUV444P):
+ granulate_ctx->PixFmt = AV_PIX_FMT_YUV444P; granulate_ctx->copy_grain_fn = copy_grain_YUV; break;
+ case (AV_PIX_FMT_GRAY8):
+ granulate_ctx->PixFmt = AV_PIX_FMT_GRAY8; granulate_ctx->copy_grain_fn = copy_grain_GRAY; break;
+ case (AV_PIX_FMT_RGB24):
+ granulate_ctx->PixFmt = AV_PIX_FMT_RGB24; granulate_ctx->copy_grain_fn = copy_grain_RGB; break;
+ case (AV_PIX_FMT_BGR24):
+ granulate_ctx->PixFmt = AV_PIX_FMT_BGR24; granulate_ctx->copy_grain_fn = copy_grain_RGB; break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ for (int i = 0; i < granulate_ctx->buffer_size; i++) {
+ AVFrame *f = granulate_ctx->fbuffer[i];
+
+ av_frame_unref(f);
+ f->format = inlink->format;
+ f->width = inlink->w;
+ f->height = inlink->h;
+
+ int ret = av_frame_get_buffer(f, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static av_always_inline void copy_px_data0(AVFrame *dst, const AVFrame *src, int d_row_offset, int s_row_offset, int d_col_offset,int s_col_offset) {
+ dst->data[0][d_row_offset * dst->linesize[0] + d_col_offset] = src->data[0][s_row_offset * src->linesize[0] + s_col_offset];
+}
+
+static av_always_inline void copy_px_data1(AVFrame *dst, const AVFrame *src, int d_row_offset, int s_row_offset, int d_col_offset,int s_col_offset) {
+ dst->data[1][d_row_offset * dst->linesize[1] + d_col_offset] = src->data[1][s_row_offset * src->linesize[1] + s_col_offset];
+}
+
+static av_always_inline void copy_px_data2(AVFrame *dst, const AVFrame *src, int d_row_offset, int s_row_offset, int d_col_offset,int s_col_offset) {
+ dst->data[2][d_row_offset * dst->linesize[2] + d_col_offset] = src->data[2][s_row_offset * src->linesize[2] + s_col_offset];
+}
+
+
+static void copy_grain_YUV(AVFrame *dst, const AVFrame *src, int sx, int sy, int dx, int dy,
+ int grain_w, int grain_h, filter_mode mode, ghosting_mode ghosting,
+ int zoom, int var_size, int PxFmt, uint8_t log2_chroma_h, uint8_t log2_chroma_w, AVLFG *lfg)
+{
+ if (var_size) {
+ grain_h = av_lfg_get(lfg) % (grain_h + 1);
+ grain_w = av_lfg_get(lfg) % (grain_w + 1);
+ }
+ int grain_w_chroma;
+ int grain_h_chroma;
+ int sx_chroma, sy_chroma;
+ int dx_chroma, dy_chroma;
+
+ if (PxFmt == AV_PIX_FMT_YUV420P) {
+ grain_w_chroma = AV_CEIL_RSHIFT(grain_w, log2_chroma_w);
+ grain_h_chroma = AV_CEIL_RSHIFT(grain_h, log2_chroma_h);
+ sx_chroma = sx >> 1;
+ sy_chroma = sy >> 1;
+ dx_chroma = dx >> 1;
+ dy_chroma = dy >> 1;
+ }
+
+
+ if (PxFmt == AV_PIX_FMT_YUV422P) {
+ grain_w_chroma = AV_CEIL_RSHIFT(grain_w, log2_chroma_w);
+ grain_h_chroma = grain_h;
+ sx_chroma = sx >> 1;
+ sy_chroma = sy;
+ dx_chroma = dx >> 1;
+ dy_chroma = dy;
+ }
+
+ if (PxFmt == AV_PIX_FMT_YUV444P) {
+ grain_w_chroma = grain_w;
+ grain_h_chroma = grain_h;
+ sx_chroma = sx;
+ sy_chroma = sy;
+ dx_chroma = dx;
+ dy_chroma = dy;
+ }
+
+ int row_step = 1;
+ int col_step = 1;
+
+ if (mode == MODE_INTERLACED_H)
+ row_step = 2;
+
+ if (mode == MODE_INTERLACED_V)
+ col_step = 2;
+
+ int d_row_offset, d_col_offset;
+ int s_row_offset, s_col_offset;
+
+ if (ghosting != 2) {
+ for (int row = 0; row < grain_h; row += row_step) {
+ d_row_offset = dy + row;
+ s_row_offset = sy + row / zoom;
+ for (int col = 0; col < grain_w; col += col_step) {
+ d_col_offset = dx + col;
+ s_col_offset = sx + col / zoom;
+ if (mode != MODE_DITHER) {
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d_col_offset, s_col_offset);
+ }
+ else {
+ if (av_lfg_get(lfg) & 1)
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d_col_offset, s_col_offset);
+ }
+ }
+ }
+ }
+ if (ghosting != 1) {
+ for (int row = 0; row < grain_h_chroma; row += row_step) {
+ d_row_offset = dy_chroma + row;
+ s_row_offset = sy_chroma + row / zoom;
+ for (int col = 0; col < grain_w_chroma; col += col_step) {
+ d_col_offset = dx_chroma + col;
+ s_col_offset = sx_chroma + col / zoom;
+ if (mode != MODE_DITHER) {
+ copy_px_data1(dst, src, d_row_offset, s_row_offset, d_col_offset, s_col_offset);
+ copy_px_data2(dst, src, d_row_offset, s_row_offset, d_col_offset, s_col_offset);
+ }
+ else {
+ if (av_lfg_get(lfg) & 1) {
+ copy_px_data1(dst, src, d_row_offset, s_row_offset, d_col_offset, s_col_offset);
+ copy_px_data2(dst, src, d_row_offset, s_row_offset, d_col_offset, s_col_offset);
+ }
+ }
+ }
+ }
+ }
+}
+
+static void copy_grain_GRAY(AVFrame *dst, const AVFrame *src, int sx, int sy, int dx, int dy,
+ int grain_w, int grain_h, filter_mode mode, ghosting_mode ghosting,
+ int zoom, int var_size, int PxFmt, uint8_t log2_chroma_h, uint8_t log2_chroma_w, AVLFG *lfg)
+{
+ if (var_size) {
+ grain_h = av_lfg_get(lfg) % (grain_h + 1);
+ grain_w = av_lfg_get(lfg) % (grain_w + 1);
+ }
+
+ int row_step = 1;
+ int col_step = 1;
+
+ if (mode == MODE_INTERLACED_H)
+ row_step = 2;
+
+ if (mode == MODE_INTERLACED_V)
+ col_step = 2;
+
+ int d_row_offset, d_col_offset;
+ int s_row_offset, s_col_offset;
+
+ for (int row = 0; row < grain_h; row += row_step) {
+ d_row_offset = dy + row;
+ s_row_offset = sy + row / zoom;
+ for (int col = 0; col < grain_w; col += col_step) {
+ d_col_offset = dx + col;
+ s_col_offset = sx + col / zoom;
+ if (mode != MODE_DITHER) {
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d_col_offset, s_col_offset);
+ }
+ else {
+ if (av_lfg_get(lfg) & 1)
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d_col_offset, s_col_offset);
+ }
+ }
+ }
+
+}
+
+static void copy_grain_RGB(AVFrame *dst, const AVFrame *src, int sx, int sy, int dx, int dy,
+ int grain_w, int grain_h, filter_mode mode, ghosting_mode ghosting,
+ int zoom, int var_size, int PxFmt, uint8_t log2_chroma_h, uint8_t log2_chroma_w, AVLFG *lfg)
+{
+ if (var_size) {
+ grain_h = av_lfg_get(lfg) % (grain_h + 1);
+ grain_w = av_lfg_get(lfg) % (grain_w + 1);
+ }
+
+ int row_step = 1;
+ int col_step = 1;
+
+ if (mode == MODE_INTERLACED_H)
+ row_step = 2;
+
+ if (mode == MODE_INTERLACED_V)
+ col_step = 2;
+
+ int d_row_offset, s_row_offset;
+ int d1_col_offset, d2_col_offset, d3_col_offset;
+ int s1_col_offset, s2_col_offset, s3_col_offset;
+
+ for (int row = 0; row < grain_h; row += row_step) {
+ d_row_offset = dy + row;
+ s_row_offset = sy + row / zoom;
+ for (int col = 0; col < grain_w; col += col_step) {
+ d1_col_offset = dx + col * 3;
+ s1_col_offset = sx + col / zoom * 3;
+ d2_col_offset = dx + col * 3 + 1;
+ s2_col_offset = sx + col / zoom * 3 + 1;
+ d3_col_offset = dx + col * 3 + 2;
+ s3_col_offset = sx + col / zoom * 3 + 2;
+ if (mode != MODE_DITHER) {
+ if (!ghosting) {
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d1_col_offset, s1_col_offset);
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d2_col_offset, s2_col_offset);
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d3_col_offset, s3_col_offset);
+ }
+ else {
+ uint32_t r = av_lfg_get(lfg);
+ if (r & 2)
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d1_col_offset, s1_col_offset);
+ if (r & 4)
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d2_col_offset, s2_col_offset);
+ if (r & 8)
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d3_col_offset, s3_col_offset);
+ }
+ }
+ else {
+ uint32_t r = av_lfg_get(lfg);
+ if (r & 1) {
+ if (!ghosting) {
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d1_col_offset, s1_col_offset);
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d2_col_offset, s2_col_offset);
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d3_col_offset, s3_col_offset);
+ }
+ else {
+ if (r & 2)
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d1_col_offset, s1_col_offset);
+ if (r & 4)
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d2_col_offset, s2_col_offset);
+ if (r & 8)
+ copy_px_data0(dst, src, d_row_offset, s_row_offset, d3_col_offset, s3_col_offset);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+static void granulate_rand(const GranulateContext *ctx, AVFrame *dst, AVFrame **src, int width, int height)
+{
+ AVFrame *src_f = NULL;
+
+ int grain_w = ctx->grain_w;
+ int grain_h = ctx->grain_h;
+ int n_grains = ctx->n_grains;
+ int offset_w = ctx->zoom_offset_w;
+ int offset_h = ctx->zoom_offset_h;
+ int g_src = 0;
+
+ if (ctx->delay_set) {
+ g_src = (ctx->delay_set + ctx->frame_count) % ctx->buffer_size;
+ src_f = src[g_src];
+ }
+
+ for (int grain_count = 0; grain_count < n_grains; grain_count++) {
+ if (!ctx->delay_set) {
+ if (ctx->buffer_full) {
+ g_src = av_lfg_get(ctx->lfg) % ctx->buffer_size;
+ src_f = src[g_src];
+ }
+ else {
+ g_src = av_lfg_get(ctx->lfg) % (ctx->buffer_index + 1);
+ src_f = src[g_src];
+ }
+ }
+ int sx = av_lfg_get(ctx->lfg) % (width - grain_w + 1);
+ int sy = av_lfg_get(ctx->lfg) % (height - grain_h + 1);
+ int dx = av_lfg_get(ctx->lfg) % (width - grain_w + 1);
+ int dy = av_lfg_get(ctx->lfg) % (height - grain_h + 1);
+
+ ctx->copy_grain_fn(dst, src_f, sx + offset_w, sy + offset_h, dx, dy, grain_w, grain_h, ctx->mode, ctx->ghosting, ctx->zoom_amount, ctx->var_size, ctx->PixFmt, ctx->log2_chroma_h, ctx->log2_chroma_w, ctx->lfg);
+ }
+}
+
+static void granulate_pos(const GranulateContext *ctx, AVFrame *dst, AVFrame **src, int width, int height)
+{
+ AVFrame *src_f = NULL;
+
+ int grain_w = ctx->grain_w;
+ int grain_h = ctx->grain_h;
+ int n_grains = ctx->n_grains;
+ int offset_w = ctx->zoom_offset_w;
+ int offset_h = ctx->zoom_offset_h;
+ GrainPos *grain_pos = ctx->grain_pos;
+ int g_src = 0;
+
+ if (ctx->delay_set) {
+ g_src = (ctx->delay_set + ctx->frame_count) % ctx->buffer_size;
+ src_f = src[g_src];
+ }
+
+ for (int grain_count = 0; grain_count < n_grains; grain_count++) {
+ if (!ctx->delay_set) {
+ if (ctx->buffer_full) {
+ g_src = av_lfg_get(ctx->lfg) % ctx->buffer_size;
+ src_f = src[g_src];
+ }
+ else {
+ g_src = av_lfg_get(ctx->lfg) % (ctx->buffer_index + 1);
+ src_f = src[g_src];
+ }
+ }
+ ctx->copy_grain_fn(dst, src_f, grain_pos[grain_count].g_pos_x + offset_w, grain_pos[grain_count].g_pos_y + offset_h, grain_pos[grain_count].pos_x, grain_pos[grain_count].pos_y, grain_w, grain_h, ctx->mode, ctx->ghosting, ctx->zoom_amount, ctx->var_size, ctx->PixFmt, ctx->log2_chroma_h, ctx->log2_chroma_w, ctx->lfg);
+ }
+}
+
+static void granulate_in_frame(const GranulateContext *ctx, AVFrame *dst, int width, int height)
+{
+
+ int grain_w = ctx->grain_w;
+ int grain_h = ctx->grain_h;
+ int n_grains = ctx->n_grains;
+ int offset_w = ctx->zoom_offset_w;
+ int offset_h = ctx->zoom_offset_h;
+
+ for (int grain_count = 0; grain_count < n_grains; grain_count++) {
+ int sx = av_lfg_get(ctx->lfg) % (width - grain_w + 1);
+ int sy = av_lfg_get(ctx->lfg) % (height - grain_h + 1);
+ int dx = av_lfg_get(ctx->lfg) % (width - grain_w + 1);
+ int dy = av_lfg_get(ctx->lfg) % (height - grain_h + 1);
+
+ ctx->copy_grain_fn(dst, ctx->fbuffer[0], sx + offset_w, sy + offset_h, dx, dy, grain_w, grain_h, ctx->mode, ctx->ghosting, ctx->zoom_amount, ctx->var_size, ctx->PixFmt, ctx->log2_chroma_h, ctx->log2_chroma_w, ctx->lfg);
+ }
+}
+
+static void init_granulate_pos(const GranulateContext *ctx, int width, int height)
+{
+
+ int grain_w = ctx->grain_w;
+ int grain_h = ctx->grain_h;
+ int n_grains = ctx->n_grains;
+ GrainPos *grain_pos = ctx->grain_pos;
+
+ for (int grain_count = 0; grain_count < n_grains; grain_count++) {
+ grain_pos[grain_count].g_pos_x = av_lfg_get(ctx->lfg) % (width - grain_w + 1);
+ grain_pos[grain_count].g_pos_y = av_lfg_get(ctx->lfg) % (height - grain_h + 1);
+ grain_pos[grain_count].pos_x = av_lfg_get(ctx->lfg) % (width - grain_w + 1);
+ grain_pos[grain_count].pos_y = av_lfg_get(ctx->lfg) % (height - grain_h + 1);
+ }
+}
+
+static void set_offset(GranulateContext *ctx) {
+ ctx->zoom_offset_w = av_lfg_get(ctx->lfg) % (ctx->grain_w - (ctx->grain_w / ctx->zoom_amount));
+ ctx->zoom_offset_h = av_lfg_get(ctx->lfg) % (ctx->grain_h - (ctx->grain_h / ctx->zoom_amount));
+}
+
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+ AVFilterContext *ctx = inlink->dst;
+ GranulateContext *granulate_ctx = ctx->priv;
+ AVFilterLink *outlink = ctx->outputs[0];
+ AVFrame *out = NULL;
+ int ret;
+
+ ret = ff_inlink_make_frame_writable(inlink, &in);
+ if (ret < 0)
+ return ret;
+
+ out = in;
+
+ if (!granulate_ctx->n_grains)
+ goto filter_end;
+
+ int width = in->width;
+ int height = in->height;
+
+ if (granulate_ctx->grain_h && granulate_ctx->grain_w)
+ granulate_ctx->fullscreen = 0;
+
+ if (!granulate_ctx->fullscreen) {
+ if (granulate_ctx->grain_w > width)
+ granulate_ctx->grain_w = width;
+ if (granulate_ctx->grain_h > height)
+ granulate_ctx->grain_h = height;
+ } else {
+ granulate_ctx->grain_w = width;
+ granulate_ctx->grain_h = height;
+ }
+
+ if (!granulate_ctx->delay)
+ granulate_ctx->delay_set = 0;
+
+ if (granulate_ctx->zoom_amount == 1) {
+ granulate_ctx->zoom_set = 0;
+ granulate_ctx->zoom_offset_w = 0;
+ granulate_ctx->zoom_offset_h = 0;
+ }
+
+ if (granulate_ctx->zoom_set && granulate_ctx->zoom_amount > 1) {
+ if (granulate_ctx->zoom_offset_w >= (granulate_ctx->grain_w - (granulate_ctx->grain_w / granulate_ctx->zoom_amount)) || granulate_ctx->zoom_offset_h >= (granulate_ctx->grain_h - (granulate_ctx->grain_h / granulate_ctx->zoom_amount)))
+ set_offset(granulate_ctx);
+ if (granulate_ctx->offset_time) {
+ if (!(granulate_ctx->frame_count % granulate_ctx->offset_time))
+ set_offset(granulate_ctx);
+ }
+ }
+
+ if (!granulate_ctx->zoom_set && granulate_ctx->zoom_amount > 1) {
+ granulate_ctx->zoom_set = 1;
+ set_offset(granulate_ctx);
+ }
+
+ if (granulate_ctx->buffer_size > 1) {
+
+ AVFrame *buf = granulate_ctx->fbuffer[granulate_ctx->buffer_index];
+ ret = av_frame_copy(buf, in);
+ if (ret < 0)
+ return ret;
+
+ if (granulate_ctx->delay && granulate_ctx->buffer_full && granulate_ctx->buffer_size > 1) {
+ if (!(granulate_ctx->frame_count % granulate_ctx->delay))
+ granulate_ctx->delay_set = 1 + (av_lfg_get(granulate_ctx->lfg) % (granulate_ctx->buffer_size - 1));
+ }
+
+ if (granulate_ctx->static_grains) {
+ if (!granulate_ctx->grains_set) {
+ init_granulate_pos(granulate_ctx, width, height);
+ granulate_ctx->grains_set = 1;
+ }
+ else if (granulate_ctx->reset_time && !(granulate_ctx->frame_count % granulate_ctx->reset_time)) {
+ init_granulate_pos(granulate_ctx, width, height);
+ granulate_pos(granulate_ctx, out, granulate_ctx->fbuffer, width, height);
+ }
+ else {
+ granulate_pos(granulate_ctx, out, granulate_ctx->fbuffer, width, height);
+ }
+ }
+ else {
+ granulate_rand(granulate_ctx, out, granulate_ctx->fbuffer, width, height);
+ }
+
+ granulate_ctx->buffer_index = (granulate_ctx->buffer_index + 1) % granulate_ctx->buffer_size;
+
+ if (!granulate_ctx->buffer_index)
+ granulate_ctx->buffer_full = 1;
+ }
+
+ else {
+ AVFrame *buf = granulate_ctx->fbuffer[0];
+ ret = av_frame_copy(buf, in);
+ if (ret < 0)
+ return ret;
+ granulate_in_frame(granulate_ctx, out, width, height);
+ }
+filter_end:
+ granulate_ctx->frame_count++;
+
+
+ return ff_filter_frame(outlink, out);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ int i;
+ GranulateContext *granulate_ctx = ctx->priv;
+
+ for (i = 0; i < granulate_ctx->buffer_size; i++)
+ av_frame_free(&granulate_ctx->fbuffer[i]);
+
+ if (granulate_ctx->static_grains && granulate_ctx->n_grains)
+ av_freep(&granulate_ctx->grain_pos);
+
+ av_freep(&granulate_ctx->fbuffer);
+ av_freep(&granulate_ctx->lfg);
+}
+
+static const AVFilterPad granulate_inputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .config_props = config_props,
+ .filter_frame = filter_frame,
+ },
+};
+
+const FFFilter ff_vf_granulate = {
+ .p.name = "granulate",
+ .p.description = NULL_IF_CONFIG_SMALL("Granulate past frames in current frame"),
+ .p.priv_class = &granulate_class,
+ .p.flags = 0,
+ .priv_size = sizeof(GranulateContext),
+ .init = init,
+ .uninit = uninit,
+ .process_command = granulate_process_command,
+ FILTER_INPUTS(granulate_inputs),
+ FILTER_OUTPUTS(ff_video_default_filterpad),
+ FILTER_QUERY_FUNC2(query_formats),
+};
diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
index 0eb2e7076c..025fcff943 100644
--- a/tests/fate/filter-video.mak
+++ b/tests/fate/filter-video.mak
@@ -492,6 +492,12 @@ fate-filter-fps-down-eof-pass: CMD = framecrc -lavfi testsrc2=r=7:d=3.5,fps=3:eo
fate-filter-fps-start-drop: CMD = framecrc -lavfi testsrc2=r=7:d=3.5,fps=3:start_time=1.5
fate-filter-fps-start-fill: CMD = framecrc -lavfi testsrc2=r=7:d=1.5,setpts=PTS+14,fps=3:start_time=1.5
+FATE_FILTER-$(call ALLYES, TESTSRC_FILTER GRANULATE_FILTER) += fate-filter-granulate-basic
+fate-filter-granulate-basic: CMD = framecrc -f lavfi -i testsrc=size=640x480:rate=25:duration=6 -vf granulate=mode=0:n_grains=1:buffer=16:zoom=1:seed=1
+
+FATE_FILTER-$(call ALLYES, TESTSRC_FILTER GRANULATE_FILTER) += fate-filter-granulate-adv
+fate-filter-granulate-adv: CMD = framecrc -f lavfi -i testsrc=size=640x480:rate=25:duration=6 -vf granulate=mode=3:zoom=2:offset_time=1:n_grains=64:buffer=64:ghosting=1:grain_w=128:grain_h=128:var_size=1:static_grains=1:reset_time=25:delay=25:seed=1
+
DRAWVG_SCRIPT_ALL = $(SRC_PATH)/tests/ref/lavf/drawvg.all
FATE_FILTER-$(CONFIG_DRAWVG_FILTER) += fate-filter-drawvg-interpreter
--
2.55.0
2
2