/src/vvdec/source/Lib/CommonLib/RdCost.cpp
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 | | /** \file RdCost.cpp |
44 | | \brief RD cost computation class |
45 | | */ |
46 | | |
47 | | #define DONT_UNDEF_SIZE_AWARE_PER_EL_OP |
48 | | |
49 | | #include "RdCost.h" |
50 | | |
51 | | namespace vvdec |
52 | | { |
53 | | |
54 | | RdCost::RdCost( bool enableOpt ) |
55 | 0 | { |
56 | 0 | m_afpDistortFunc[DF_SAD8 ] = RdCost::xGetSAD8; |
57 | 0 | m_afpDistortFunc[DF_SAD16 ] = RdCost::xGetSAD16; |
58 | | |
59 | 0 | m_afpDistortFuncX5[DF_SAD8 ] = RdCost::xGetSAD8X5; |
60 | 0 | m_afpDistortFuncX5[DF_SAD16 ] = RdCost::xGetSAD16X5; |
61 | |
|
62 | 0 | if( enableOpt ) |
63 | 0 | { |
64 | 0 | #if ENABLE_SIMD_OPT_DIST |
65 | 0 | #ifdef TARGET_SIMD_X86 |
66 | 0 | initRdCostX86(); |
67 | 0 | #endif |
68 | | #ifdef TARGET_SIMD_ARM |
69 | | initRdCostARM(); |
70 | | #endif |
71 | 0 | #endif |
72 | 0 | } |
73 | 0 | } |
74 | | |
75 | | RdCost::~RdCost() |
76 | 0 | { |
77 | 0 | } |
78 | | |
79 | | void RdCost::setDistParam( DistParam &rcDP, const Pel* pOrg, const Pel* piRefY, ptrdiff_t iOrgStride, ptrdiff_t iRefStride, int bitDepth, int width, int height, int subShiftMode ) |
80 | 0 | { |
81 | 0 | rcDP.bitDepth = bitDepth; |
82 | |
|
83 | 0 | rcDP.org.buf = pOrg; |
84 | 0 | rcDP.org.stride = iOrgStride; |
85 | 0 | rcDP.org.width = width; |
86 | 0 | rcDP.org.height = height; |
87 | |
|
88 | 0 | rcDP.cur.buf = piRefY; |
89 | 0 | rcDP.cur.stride = iRefStride; |
90 | 0 | rcDP.cur.width = width; |
91 | 0 | rcDP.cur.height = height; |
92 | |
|
93 | 0 | rcDP.subShift = subShiftMode; |
94 | |
|
95 | 0 | rcDP.distFunc = m_afpDistortFunc[getLog2( width ) - 3]; |
96 | 0 | rcDP.distFuncX5 = m_afpDistortFuncX5[getLog2( width ) - 3]; |
97 | 0 | } |
98 | | |
99 | | // ==================================================================================================================== |
100 | | // Distortion functions |
101 | | // ==================================================================================================================== |
102 | | |
103 | | // -------------------------------------------------------------------------------------------------------------------- |
104 | | // SAD |
105 | | // -------------------------------------------------------------------------------------------------------------------- |
106 | | |
107 | | Distortion RdCost::xGetSAD8( const DistParam& rcDtParam ) |
108 | 0 | { |
109 | 0 | const Pel* piOrg = rcDtParam.org.buf; |
110 | 0 | const Pel* piCur = rcDtParam.cur.buf; |
111 | 0 | int iRows = rcDtParam.org.height; |
112 | 0 | int iSubShift = rcDtParam.subShift; |
113 | 0 | int iSubStep = ( 1 << iSubShift ); |
114 | 0 | ptrdiff_t iStrideCur = rcDtParam.cur.stride * iSubStep; |
115 | 0 | ptrdiff_t iStrideOrg = rcDtParam.org.stride * iSubStep; |
116 | |
|
117 | 0 | Distortion uiSum = 0; |
118 | |
|
119 | 0 | for( ; iRows != 0; iRows-=iSubStep ) |
120 | 0 | { |
121 | 0 | uiSum += abs( piOrg[0] - piCur[0] ); |
122 | 0 | uiSum += abs( piOrg[1] - piCur[1] ); |
123 | 0 | uiSum += abs( piOrg[2] - piCur[2] ); |
124 | 0 | uiSum += abs( piOrg[3] - piCur[3] ); |
125 | 0 | uiSum += abs( piOrg[4] - piCur[4] ); |
126 | 0 | uiSum += abs( piOrg[5] - piCur[5] ); |
127 | 0 | uiSum += abs( piOrg[6] - piCur[6] ); |
128 | 0 | uiSum += abs( piOrg[7] - piCur[7] ); |
129 | |
|
130 | 0 | piOrg += iStrideOrg; |
131 | 0 | piCur += iStrideCur; |
132 | 0 | } |
133 | |
|
134 | 0 | uiSum <<= iSubShift; |
135 | 0 | return uiSum; |
136 | 0 | } |
137 | | |
138 | | Distortion RdCost::xGetSAD16( const DistParam& rcDtParam ) |
139 | 0 | { |
140 | 0 | const Pel* piOrg = rcDtParam.org.buf; |
141 | 0 | const Pel* piCur = rcDtParam.cur.buf; |
142 | 0 | int iRows = rcDtParam.org.height; |
143 | 0 | int iSubShift = rcDtParam.subShift; |
144 | 0 | int iSubStep = ( 1 << iSubShift ); |
145 | 0 | ptrdiff_t iStrideCur = rcDtParam.cur.stride * iSubStep; |
146 | 0 | ptrdiff_t iStrideOrg = rcDtParam.org.stride * iSubStep; |
147 | |
|
148 | 0 | Distortion uiSum = 0; |
149 | |
|
150 | 0 | for( ; iRows != 0; iRows -= iSubStep ) |
151 | 0 | { |
152 | 0 | uiSum += abs( piOrg[0] - piCur[0] ); |
153 | 0 | uiSum += abs( piOrg[1] - piCur[1] ); |
154 | 0 | uiSum += abs( piOrg[2] - piCur[2] ); |
155 | 0 | uiSum += abs( piOrg[3] - piCur[3] ); |
156 | 0 | uiSum += abs( piOrg[4] - piCur[4] ); |
157 | 0 | uiSum += abs( piOrg[5] - piCur[5] ); |
158 | 0 | uiSum += abs( piOrg[6] - piCur[6] ); |
159 | 0 | uiSum += abs( piOrg[7] - piCur[7] ); |
160 | 0 | uiSum += abs( piOrg[8] - piCur[8] ); |
161 | 0 | uiSum += abs( piOrg[9] - piCur[9] ); |
162 | 0 | uiSum += abs( piOrg[10] - piCur[10] ); |
163 | 0 | uiSum += abs( piOrg[11] - piCur[11] ); |
164 | 0 | uiSum += abs( piOrg[12] - piCur[12] ); |
165 | 0 | uiSum += abs( piOrg[13] - piCur[13] ); |
166 | 0 | uiSum += abs( piOrg[14] - piCur[14] ); |
167 | 0 | uiSum += abs( piOrg[15] - piCur[15] ); |
168 | |
|
169 | 0 | piOrg += iStrideOrg; |
170 | 0 | piCur += iStrideCur; |
171 | 0 | } |
172 | |
|
173 | 0 | uiSum <<= iSubShift; |
174 | 0 | return uiSum; |
175 | 0 | } |
176 | | |
177 | 0 | void RdCost::xGetSAD8X5(const DistParam& rcDtParam, Distortion* cost, bool isCalCentrePos) { |
178 | 0 | DistParam rcDtParamTmp0 = rcDtParam; |
179 | 0 | DistParam rcDtParamTmp1 = rcDtParam; |
180 | 0 | rcDtParamTmp1.org.buf += 1; |
181 | 0 | rcDtParamTmp1.cur.buf -= 1; |
182 | 0 | DistParam rcDtParamTmp2 = rcDtParam; |
183 | 0 | rcDtParamTmp2.org.buf += 2; |
184 | 0 | rcDtParamTmp2.cur.buf -= 2; |
185 | 0 | DistParam rcDtParamTmp3 = rcDtParam; |
186 | 0 | rcDtParamTmp3.org.buf += 3; |
187 | 0 | rcDtParamTmp3.cur.buf -= 3; |
188 | 0 | DistParam rcDtParamTmp4 = rcDtParam; |
189 | 0 | rcDtParamTmp4.org.buf += 4; |
190 | 0 | rcDtParamTmp4.cur.buf -= 4; |
191 | | |
192 | 0 | cost[0] = (RdCost::xGetSAD8(rcDtParamTmp0)) >> 1; |
193 | 0 | cost[1] = (RdCost::xGetSAD8(rcDtParamTmp1)) >> 1; |
194 | 0 | if (isCalCentrePos) cost[2] = (RdCost::xGetSAD8(rcDtParamTmp2)) >> 1; |
195 | 0 | cost[3] = (RdCost::xGetSAD8(rcDtParamTmp3)) >> 1; |
196 | 0 | cost[4] = (RdCost::xGetSAD8(rcDtParamTmp4)) >> 1; |
197 | 0 | } |
198 | | |
199 | 0 | void RdCost::xGetSAD16X5(const DistParam& rcDtParam, Distortion* cost, bool isCalCentrePos) { |
200 | 0 | DistParam rcDtParamTmp0 = rcDtParam; |
201 | 0 | DistParam rcDtParamTmp1 = rcDtParam; |
202 | 0 | rcDtParamTmp1.org.buf += 1; |
203 | 0 | rcDtParamTmp1.cur.buf -= 1; |
204 | 0 | DistParam rcDtParamTmp2 = rcDtParam; |
205 | 0 | rcDtParamTmp2.org.buf += 2; |
206 | 0 | rcDtParamTmp2.cur.buf -= 2; |
207 | 0 | DistParam rcDtParamTmp3 = rcDtParam; |
208 | 0 | rcDtParamTmp3.org.buf += 3; |
209 | 0 | rcDtParamTmp3.cur.buf -= 3; |
210 | 0 | DistParam rcDtParamTmp4 = rcDtParam; |
211 | 0 | rcDtParamTmp4.org.buf += 4; |
212 | 0 | rcDtParamTmp4.cur.buf -= 4; |
213 | | |
214 | 0 | cost[0] = (RdCost::xGetSAD16(rcDtParamTmp0)) >> 1; |
215 | 0 | cost[1] = (RdCost::xGetSAD16(rcDtParamTmp1)) >> 1; |
216 | 0 | if (isCalCentrePos) cost[2] = (RdCost::xGetSAD16(rcDtParamTmp2)) >> 1; |
217 | 0 | cost[3] = (RdCost::xGetSAD16(rcDtParamTmp3)) >> 1; |
218 | 0 | cost[4] = (RdCost::xGetSAD16(rcDtParamTmp4)) >> 1; |
219 | 0 | } |
220 | | |
221 | | } |