/src/vvdec/source/Lib/FilmGrain/FilmGrainImpl.h
Line | Count | Source |
1 | | /* ----------------------------------------------------------------------------- |
2 | | The copyright in this software is being made available under the Clear BSD |
3 | | License, included below. No patent rights, trademark rights and/or |
4 | | other Intellectual Property Rights other than the copyrights concerning |
5 | | the Software are granted under this license. |
6 | | |
7 | | The Clear BSD License |
8 | | |
9 | | Copyright (c) 2018-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVdeC Authors. |
10 | | All rights reserved. |
11 | | |
12 | | Redistribution and use in source and binary forms, with or without modification, |
13 | | are permitted (subject to the limitations in the disclaimer below) provided that |
14 | | the following conditions are met: |
15 | | |
16 | | * Redistributions of source code must retain the above copyright notice, |
17 | | this list of conditions and the following disclaimer. |
18 | | |
19 | | * Redistributions in binary form must reproduce the above copyright |
20 | | notice, this list of conditions and the following disclaimer in the |
21 | | documentation and/or other materials provided with the distribution. |
22 | | |
23 | | * Neither the name of the copyright holder nor the names of its |
24 | | contributors may be used to endorse or promote products derived from this |
25 | | software without specific prior written permission. |
26 | | |
27 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY |
28 | | THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
29 | | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
30 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
31 | | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
32 | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
33 | | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
34 | | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
35 | | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
36 | | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
37 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38 | | POSSIBILITY OF SUCH DAMAGE. |
39 | | |
40 | | |
41 | | ------------------------------------------------------------------------------------------- */ |
42 | | |
43 | | /* This file is based on VFGS, available on |
44 | | * https://github.com/InterDigitalInc/VersatileFilmGrain |
45 | | * |
46 | | * VFGS implements film grain synthesis as a hardware model: it simulates the |
47 | | * output of a cost-effective hardware implementation in a video display |
48 | | * pipeline. Also, the C code is split into "fw" (firmware) and "hw" (hardware) |
49 | | * parts, and as self-explanatory as possible. See VFGS github repository for |
50 | | * more details. |
51 | | * |
52 | | * The VFGS github repository also contains other tools to experiment with film |
53 | | * grain synthesis (e.g. a graphical display and tuning tool for FGC SEI |
54 | | * message). |
55 | | */ |
56 | | |
57 | | #pragma once |
58 | | |
59 | | #include <cstdint> |
60 | | |
61 | 0 | #define VFGS_MAX_PATTERNS 8 |
62 | | #define PATTERN_INTERPOLATION 0 |
63 | | |
64 | | namespace vvdec |
65 | | { |
66 | | |
67 | | /** Pseudo-random number generator (32-bit) |
68 | | * Note: loops on the 31 MSBs, so seed should be MSB-aligned in the register |
69 | | * (the register LSB has basically no effect since it is never fed back) |
70 | | */ |
71 | | static inline uint32_t prng( uint32_t x ) |
72 | 0 | { |
73 | 0 | #if 1 // same as HW (bit-reversed RDD-5) |
74 | 0 | uint32_t s = ( ( x << 30 ) ^ ( x << 2 ) ) & 0x80000000; |
75 | 0 | x = s | ( x >> 1 ); |
76 | | #else // RDD-5 |
77 | | uint32_t s = ( ( x >> 30 ) ^ ( x >> 2 ) ) & 1; |
78 | | x = ( x << 1 ) | s; |
79 | | #endif |
80 | 0 | return x; |
81 | 0 | } Unexecuted instantiation: vvdecimpl.cpp:vvdec::prng(unsigned int) Unexecuted instantiation: FilmGrain.cpp:vvdec::prng(unsigned int) Unexecuted instantiation: FilmGrainImpl.cpp:vvdec::prng(unsigned int) Unexecuted instantiation: FilmGrainImpl_sse41.cpp:vvdec::prng(unsigned int) Unexecuted instantiation: FilmGrainImpl_avx2.cpp:vvdec::prng(unsigned int) |
82 | | |
83 | | template<class T> |
84 | | constexpr inline auto round( T a, uint8_t s ) |
85 | 0 | { |
86 | 0 | return ( a + ( 1 << ( s - 1 ) ) ) >> s; |
87 | 0 | } Unexecuted instantiation: auto vvdec::round<int>(int, unsigned char) Unexecuted instantiation: auto vvdec::round<signed char>(signed char, unsigned char) |
88 | | |
89 | | class FilmGrainImpl |
90 | | { |
91 | | protected: |
92 | | // Note: declarations optimized for code readability; e.g. pattern storage in |
93 | | // actual hardware implementation would differ significantly |
94 | | int8_t pattern[2][VFGS_MAX_PATTERNS + 1][64][64]; // +1 to simplify interpolation code |
95 | | uint8_t sLUT[3][256]; |
96 | | uint8_t pLUT[3][256]; |
97 | | |
98 | | uint8_t scale_shift = 5 + 6; |
99 | | uint8_t bs = 0; // bitshift = bitdepth - 8 |
100 | | int csubx = 2; |
101 | | int csuby = 2; |
102 | | bool allZero[3] = { 0, 0, 0 }; |
103 | | |
104 | | constexpr static uint8_t Y_min = 0; |
105 | | constexpr static uint8_t Y_max = 255; |
106 | | constexpr static uint8_t C_min = 0; |
107 | | constexpr static uint8_t C_max = 255; |
108 | | |
109 | | static void get_offset_y( uint32_t val, int* s, uint8_t* x, uint8_t* y ); |
110 | | void get_offset_u( uint32_t val, int* s, uint8_t* x, uint8_t* y ) const; |
111 | | void get_offset_v( uint32_t val, int* s, uint8_t* x, uint8_t* y ) const; |
112 | | |
113 | | public: |
114 | | FilmGrainImpl(); |
115 | 0 | virtual ~FilmGrainImpl() = default; |
116 | | |
117 | | void add_grain_block( void* I, int c, int x, int y, int width, uint32_t rnd, uint32_t rnd_up, int16_t grain[3][32], uint8_t scale[3][32] ) const; |
118 | | void set_luma_pattern( int index, int8_t* P ); |
119 | | void set_chroma_pattern( int index, int8_t* P ); |
120 | | void set_scale_lut( int c, uint8_t lut[] ); |
121 | | void set_pattern_lut( int c, uint8_t lut[], bool all0 ); |
122 | | void set_scale_shift( int shift ); |
123 | | |
124 | | void set_depth( int depth ); |
125 | | void set_chroma_subsampling( int subx, int suby ); |
126 | | |
127 | | private: |
128 | | virtual void make_grain_pattern( const void* I, |
129 | | int c, |
130 | | int x, |
131 | | int subx, |
132 | | uint8_t oc1, |
133 | | uint8_t oc2, |
134 | | uint8_t ox, |
135 | | uint8_t ox_up, |
136 | | uint8_t oy, |
137 | | uint8_t oy_up, |
138 | | int s, |
139 | | int s_up, |
140 | | int16_t grain[3][32], |
141 | | uint8_t scale[3][32] ) const; |
142 | | virtual void scale_and_output( void* I, // |
143 | | int c, |
144 | | int x, |
145 | | int subx, |
146 | | int width, |
147 | | int16_t grain[3][32], |
148 | | uint8_t scale[3][32] ) const; |
149 | | }; |
150 | | |
151 | | } // namespace vvdec |