summaryrefslogtreecommitdiff
path: root/libavcodec/h274.h
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2021-08-17 21:25:32 +0200
committerJames Almer <jamrial@gmail.com>2021-08-24 09:58:52 -0300
commit6bc29a6b571c83058d04dc7b8b0f827dfee31b2c (patch)
tree1ef02885ae312ecb9097a30da956b6f5d996a228 /libavcodec/h274.h
parentcf37c3fb6c84d8eb61079520b4c57e3c969bc25d (diff)
avcodec/h274: add film grain synthesis routine
This could arguably also be a vf, but I decided to put it here since decoders are technically required to apply film grain during the output step, and I would rather want to avoid requiring users insert the correct film grain synthesis filter on their own. The code, while in C, is written in a way that unrolls/vectorizes fairly well under -O3, and is reasonably cache friendly. On my CPU, a single thread pushes about 400 FPS at 1080p. Apart from hand-written assembly, one possible avenue of improvement would be to change the access order to compute the grain row-by-row rather than in 8x8 blocks. This requires some redundant PRNG calls, but would make the algorithm more cache-oblivious. The implementation has been written to the wording of SMPTE RDD 5-2006 as faithfully as I can manage. However, apart from passing a visual inspection, no guarantee of correctness can be made due to the lack of any publicly available reference implementation against which to compare it. Signed-off-by: Niklas Haas <git@haasn.dev> Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec/h274.h')
-rw-r--r--libavcodec/h274.h52
1 files changed, 52 insertions, 0 deletions
diff --git a/libavcodec/h274.h b/libavcodec/h274.h
new file mode 100644
index 0000000000..807b3a016a
--- /dev/null
+++ b/libavcodec/h274.h
@@ -0,0 +1,52 @@
+/*
+ * H.274 film grain synthesis
+ * Copyright (c) 2021 Niklas Haas <ffmpeg@haasn.xyz>
+ *
+ * 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
+ * H.274 film grain synthesis.
+ * @author Niklas Haas <ffmpeg@haasn.xyz>
+ */
+
+#ifndef AVCODEC_H274_H
+#define AVCODEC_H274_H
+
+#include <libavutil/film_grain_params.h>
+
+// Must be initialized to {0} prior to first usage
+typedef struct H274FilmGrainDatabase {
+ // Database of film grain patterns, lazily computed as-needed
+ int8_t db[13 /* h */][13 /* v */][64][64];
+ uint16_t residency[13 /* h */]; // bit field of v
+
+ // Temporary buffer for slice generation
+ int16_t slice_tmp[64][64];
+} H274FilmGrainDatabase;
+
+// Synthesizes film grain on top of `in` and stores the result to `out`. `out`
+// must already have been allocated and set to the same size and format as
+// `in`.
+//
+// Returns a negative error code on error, such as invalid params.
+int ff_h274_apply_film_grain(AVFrame *out, const AVFrame *in,
+ H274FilmGrainDatabase *db,
+ const AVFilmGrainParams *params);
+
+#endif /* AVCODEC_H274_H */