Coverage Report

Created: 2026-10-28 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/vvenc/source/Lib/CommonLib/Buffer.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) 2019-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVenC 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
44
/** \file     Buffer.cpp
45
 *  \brief    Low-overhead class describing 2D memory layout
46
 */
47
48
#define DONT_UNDEF_SIZE_AWARE_PER_EL_OP
49
50
// unit needs to come first due to a forward declaration
51
#include "Unit.h"
52
#include "Slice.h"
53
#include "InterpolationFilter.h"
54
55
//! \ingroup CommonLib
56
//! \{
57
58
namespace vvenc {
59
60
void weightCiipCore( Pel* res, const Pel* src, const int numSamples, int numIntra )
61
0
{
62
0
  if( numIntra == 1 )
63
0
  {
64
0
    for (int n = 0; n < numSamples; n+=2)
65
0
    {
66
0
      res[n  ] = (res[n  ] + src[n  ] + 1) >> 1;
67
0
      res[n+1] = (res[n+1] + src[n+1] + 1) >> 1;
68
0
    }
69
0
  }
70
0
  else
71
0
  {
72
0
    const Pel* scale   = numIntra ? src : res;
73
0
    const Pel* unscale = numIntra ? res : src;
74
75
0
    for (int n = 0; n < numSamples; n+=2)
76
0
    {
77
0
      res[n  ] = (unscale[n  ] + 3*scale[n  ] + 2) >> 2;
78
0
      res[n+1] = (unscale[n+1] + 3*scale[n+1] + 2) >> 2;
79
0
    }
80
0
  }
81
0
}
82
83
template< SizeType predPredSize, unsigned log2UpsmpFactor>
84
static void mipUpsampleHorCore(Pel* const dst, const Pel* const src, const Pel* const bndry, const SizeType dstStride, const SizeType bndryStep )
85
319k
{
86
319k
  const int roundingOffset   = 1 << (log2UpsmpFactor - 1);
87
319k
  const SizeType upsmpFactor = 1 << log2UpsmpFactor;
88
89
319k
        Pel* dstLine   = dst;
90
319k
  const Pel* srcLine   = src;
91
319k
  const Pel* bndryLine = bndry + bndryStep - 1;
92
93
2.84M
  for( SizeType idxOrthDim = 0; idxOrthDim < predPredSize; idxOrthDim++ )
94
2.52M
  {
95
2.52M
    const Pel* before  = bndryLine;
96
2.52M
    const Pel* behind  = srcLine;
97
2.52M
          Pel* currDst = dstLine;
98
22.5M
    for( SizeType idxUpsmpDim = 0; idxUpsmpDim < predPredSize; idxUpsmpDim++ )
99
20.0M
    {
100
20.0M
      const int valDiff   = *behind - *before;
101
20.0M
            int scaledVal = ( ( *before ) << log2UpsmpFactor ) + roundingOffset;
102
110M
      for( SizeType pos = 0; pos < upsmpFactor; pos++)
103
90.5M
      {
104
90.5M
        scaledVal += valDiff;
105
90.5M
        *currDst   = scaledVal >> log2UpsmpFactor;
106
90.5M
        currDst++;
107
90.5M
      }
108
20.0M
      before = behind;
109
20.0M
      behind ++;
110
20.0M
    }
111
112
2.52M
    srcLine   += predPredSize;
113
2.52M
    dstLine   += dstStride;
114
2.52M
    bndryLine += bndryStep;
115
2.52M
  }
116
319k
}
Buffer.cpp:void vvenc::mipUpsampleHorCore<4u, 1u>(short*, short const*, short const*, unsigned int, unsigned int)
Line
Count
Source
85
8.35k
{
86
8.35k
  const int roundingOffset   = 1 << (log2UpsmpFactor - 1);
87
8.35k
  const SizeType upsmpFactor = 1 << log2UpsmpFactor;
88
89
8.35k
        Pel* dstLine   = dst;
90
8.35k
  const Pel* srcLine   = src;
91
8.35k
  const Pel* bndryLine = bndry + bndryStep - 1;
92
93
41.7k
  for( SizeType idxOrthDim = 0; idxOrthDim < predPredSize; idxOrthDim++ )
94
33.4k
  {
95
33.4k
    const Pel* before  = bndryLine;
96
33.4k
    const Pel* behind  = srcLine;
97
33.4k
          Pel* currDst = dstLine;
98
167k
    for( SizeType idxUpsmpDim = 0; idxUpsmpDim < predPredSize; idxUpsmpDim++ )
99
133k
    {
100
133k
      const int valDiff   = *behind - *before;
101
133k
            int scaledVal = ( ( *before ) << log2UpsmpFactor ) + roundingOffset;
102
400k
      for( SizeType pos = 0; pos < upsmpFactor; pos++)
103
267k
      {
104
267k
        scaledVal += valDiff;
105
267k
        *currDst   = scaledVal >> log2UpsmpFactor;
106
267k
        currDst++;
107
267k
      }
108
133k
      before = behind;
109
133k
      behind ++;
110
133k
    }
111
112
33.4k
    srcLine   += predPredSize;
113
33.4k
    dstLine   += dstStride;
114
33.4k
    bndryLine += bndryStep;
115
33.4k
  }
116
8.35k
}
Unexecuted instantiation: Buffer.cpp:void vvenc::mipUpsampleHorCore<4u, 2u>(short*, short const*, short const*, unsigned int, unsigned int)
Unexecuted instantiation: Buffer.cpp:void vvenc::mipUpsampleHorCore<4u, 3u>(short*, short const*, short const*, unsigned int, unsigned int)
Buffer.cpp:void vvenc::mipUpsampleHorCore<8u, 1u>(short*, short const*, short const*, unsigned int, unsigned int)
Line
Count
Source
85
97.5k
{
86
97.5k
  const int roundingOffset   = 1 << (log2UpsmpFactor - 1);
87
97.5k
  const SizeType upsmpFactor = 1 << log2UpsmpFactor;
88
89
97.5k
        Pel* dstLine   = dst;
90
97.5k
  const Pel* srcLine   = src;
91
97.5k
  const Pel* bndryLine = bndry + bndryStep - 1;
92
93
878k
  for( SizeType idxOrthDim = 0; idxOrthDim < predPredSize; idxOrthDim++ )
94
780k
  {
95
780k
    const Pel* before  = bndryLine;
96
780k
    const Pel* behind  = srcLine;
97
780k
          Pel* currDst = dstLine;
98
7.02M
    for( SizeType idxUpsmpDim = 0; idxUpsmpDim < predPredSize; idxUpsmpDim++ )
99
6.24M
    {
100
6.24M
      const int valDiff   = *behind - *before;
101
6.24M
            int scaledVal = ( ( *before ) << log2UpsmpFactor ) + roundingOffset;
102
18.7M
      for( SizeType pos = 0; pos < upsmpFactor; pos++)
103
12.4M
      {
104
12.4M
        scaledVal += valDiff;
105
12.4M
        *currDst   = scaledVal >> log2UpsmpFactor;
106
12.4M
        currDst++;
107
12.4M
      }
108
6.24M
      before = behind;
109
6.24M
      behind ++;
110
6.24M
    }
111
112
780k
    srcLine   += predPredSize;
113
780k
    dstLine   += dstStride;
114
780k
    bndryLine += bndryStep;
115
780k
  }
116
97.5k
}
Buffer.cpp:void vvenc::mipUpsampleHorCore<8u, 2u>(short*, short const*, short const*, unsigned int, unsigned int)
Line
Count
Source
85
123k
{
86
123k
  const int roundingOffset   = 1 << (log2UpsmpFactor - 1);
87
123k
  const SizeType upsmpFactor = 1 << log2UpsmpFactor;
88
89
123k
        Pel* dstLine   = dst;
90
123k
  const Pel* srcLine   = src;
91
123k
  const Pel* bndryLine = bndry + bndryStep - 1;
92
93
1.11M
  for( SizeType idxOrthDim = 0; idxOrthDim < predPredSize; idxOrthDim++ )
94
989k
  {
95
989k
    const Pel* before  = bndryLine;
96
989k
    const Pel* behind  = srcLine;
97
989k
          Pel* currDst = dstLine;
98
8.90M
    for( SizeType idxUpsmpDim = 0; idxUpsmpDim < predPredSize; idxUpsmpDim++ )
99
7.91M
    {
100
7.91M
      const int valDiff   = *behind - *before;
101
7.91M
            int scaledVal = ( ( *before ) << log2UpsmpFactor ) + roundingOffset;
102
39.5M
      for( SizeType pos = 0; pos < upsmpFactor; pos++)
103
31.6M
      {
104
31.6M
        scaledVal += valDiff;
105
31.6M
        *currDst   = scaledVal >> log2UpsmpFactor;
106
31.6M
        currDst++;
107
31.6M
      }
108
7.91M
      before = behind;
109
7.91M
      behind ++;
110
7.91M
    }
111
112
989k
    srcLine   += predPredSize;
113
989k
    dstLine   += dstStride;
114
989k
    bndryLine += bndryStep;
115
989k
  }
116
123k
}
Buffer.cpp:void vvenc::mipUpsampleHorCore<8u, 3u>(short*, short const*, short const*, unsigned int, unsigned int)
Line
Count
Source
85
90.1k
{
86
90.1k
  const int roundingOffset   = 1 << (log2UpsmpFactor - 1);
87
90.1k
  const SizeType upsmpFactor = 1 << log2UpsmpFactor;
88
89
90.1k
        Pel* dstLine   = dst;
90
90.1k
  const Pel* srcLine   = src;
91
90.1k
  const Pel* bndryLine = bndry + bndryStep - 1;
92
93
810k
  for( SizeType idxOrthDim = 0; idxOrthDim < predPredSize; idxOrthDim++ )
94
720k
  {
95
720k
    const Pel* before  = bndryLine;
96
720k
    const Pel* behind  = srcLine;
97
720k
          Pel* currDst = dstLine;
98
6.48M
    for( SizeType idxUpsmpDim = 0; idxUpsmpDim < predPredSize; idxUpsmpDim++ )
99
5.76M
    {
100
5.76M
      const int valDiff   = *behind - *before;
101
5.76M
            int scaledVal = ( ( *before ) << log2UpsmpFactor ) + roundingOffset;
102
51.9M
      for( SizeType pos = 0; pos < upsmpFactor; pos++)
103
46.1M
      {
104
46.1M
        scaledVal += valDiff;
105
46.1M
        *currDst   = scaledVal >> log2UpsmpFactor;
106
46.1M
        currDst++;
107
46.1M
      }
108
5.76M
      before = behind;
109
5.76M
      behind ++;
110
5.76M
    }
111
112
720k
    srcLine   += predPredSize;
113
720k
    dstLine   += dstStride;
114
720k
    bndryLine += bndryStep;
115
720k
  }
116
90.1k
}
117
118
template< SizeType inHeight, unsigned log2UpsmpFactor>
119
static void mipUpsampleVerCore(Pel* const dst, const Pel* const src, const Pel* const bndry, const SizeType outWidth, const SizeType srcStep  )
120
318k
{
121
318k
  const int roundingOffset   = 1 << (log2UpsmpFactor - 1);
122
318k
  const SizeType upsmpFactor = 1 << log2UpsmpFactor;
123
124
318k
        Pel* dstLine   = dst;
125
318k
  const Pel* srcLine   = src;
126
318k
  const Pel* bndryLine = bndry;
127
128
11.5M
  for( SizeType idxOrthDim = 0; idxOrthDim < outWidth; idxOrthDim++ )
129
11.2M
  {
130
11.2M
    const Pel* before  = bndryLine;
131
11.2M
    const Pel* behind  = srcLine;
132
11.2M
          Pel* currDst = dstLine;
133
100M
    for( SizeType idxUpsmpDim = 0; idxUpsmpDim < inHeight; idxUpsmpDim++ )
134
89.6M
    {
135
89.6M
      const int valDiff   = *behind - *before;
136
89.6M
            int scaledVal = ( ( *before ) << log2UpsmpFactor ) + roundingOffset;
137
138
596M
      for( SizeType pos = 0; pos < upsmpFactor; pos++)
139
506M
      {
140
506M
        scaledVal += valDiff;
141
506M
        *currDst   = scaledVal >> log2UpsmpFactor;
142
506M
        currDst += outWidth;
143
506M
      }
144
89.6M
      before = behind;
145
89.6M
      behind += srcStep;
146
89.6M
    }
147
148
11.2M
    srcLine ++;
149
11.2M
    dstLine ++;
150
11.2M
    bndryLine ++;
151
11.2M
  }
152
318k
}
Buffer.cpp:void vvenc::mipUpsampleVerCore<4u, 1u>(short*, short const*, short const*, unsigned int, unsigned int)
Line
Count
Source
120
8.35k
{
121
8.35k
  const int roundingOffset   = 1 << (log2UpsmpFactor - 1);
122
8.35k
  const SizeType upsmpFactor = 1 << log2UpsmpFactor;
123
124
8.35k
        Pel* dstLine   = dst;
125
8.35k
  const Pel* srcLine   = src;
126
8.35k
  const Pel* bndryLine = bndry;
127
128
75.1k
  for( SizeType idxOrthDim = 0; idxOrthDim < outWidth; idxOrthDim++ )
129
66.8k
  {
130
66.8k
    const Pel* before  = bndryLine;
131
66.8k
    const Pel* behind  = srcLine;
132
66.8k
          Pel* currDst = dstLine;
133
334k
    for( SizeType idxUpsmpDim = 0; idxUpsmpDim < inHeight; idxUpsmpDim++ )
134
267k
    {
135
267k
      const int valDiff   = *behind - *before;
136
267k
            int scaledVal = ( ( *before ) << log2UpsmpFactor ) + roundingOffset;
137
138
801k
      for( SizeType pos = 0; pos < upsmpFactor; pos++)
139
534k
      {
140
534k
        scaledVal += valDiff;
141
534k
        *currDst   = scaledVal >> log2UpsmpFactor;
142
534k
        currDst += outWidth;
143
534k
      }
144
267k
      before = behind;
145
267k
      behind += srcStep;
146
267k
    }
147
148
66.8k
    srcLine ++;
149
66.8k
    dstLine ++;
150
66.8k
    bndryLine ++;
151
66.8k
  }
152
8.35k
}
Unexecuted instantiation: Buffer.cpp:void vvenc::mipUpsampleVerCore<4u, 2u>(short*, short const*, short const*, unsigned int, unsigned int)
Unexecuted instantiation: Buffer.cpp:void vvenc::mipUpsampleVerCore<4u, 3u>(short*, short const*, short const*, unsigned int, unsigned int)
Buffer.cpp:void vvenc::mipUpsampleVerCore<8u, 1u>(short*, short const*, short const*, unsigned int, unsigned int)
Line
Count
Source
120
91.1k
{
121
91.1k
  const int roundingOffset   = 1 << (log2UpsmpFactor - 1);
122
91.1k
  const SizeType upsmpFactor = 1 << log2UpsmpFactor;
123
124
91.1k
        Pel* dstLine   = dst;
125
91.1k
  const Pel* srcLine   = src;
126
91.1k
  const Pel* bndryLine = bndry;
127
128
2.34M
  for( SizeType idxOrthDim = 0; idxOrthDim < outWidth; idxOrthDim++ )
129
2.25M
  {
130
2.25M
    const Pel* before  = bndryLine;
131
2.25M
    const Pel* behind  = srcLine;
132
2.25M
          Pel* currDst = dstLine;
133
20.2M
    for( SizeType idxUpsmpDim = 0; idxUpsmpDim < inHeight; idxUpsmpDim++ )
134
18.0M
    {
135
18.0M
      const int valDiff   = *behind - *before;
136
18.0M
            int scaledVal = ( ( *before ) << log2UpsmpFactor ) + roundingOffset;
137
138
54.0M
      for( SizeType pos = 0; pos < upsmpFactor; pos++)
139
36.0M
      {
140
36.0M
        scaledVal += valDiff;
141
36.0M
        *currDst   = scaledVal >> log2UpsmpFactor;
142
36.0M
        currDst += outWidth;
143
36.0M
      }
144
18.0M
      before = behind;
145
18.0M
      behind += srcStep;
146
18.0M
    }
147
148
2.25M
    srcLine ++;
149
2.25M
    dstLine ++;
150
2.25M
    bndryLine ++;
151
2.25M
  }
152
91.1k
}
Buffer.cpp:void vvenc::mipUpsampleVerCore<8u, 2u>(short*, short const*, short const*, unsigned int, unsigned int)
Line
Count
Source
120
128k
{
121
128k
  const int roundingOffset   = 1 << (log2UpsmpFactor - 1);
122
128k
  const SizeType upsmpFactor = 1 << log2UpsmpFactor;
123
124
128k
        Pel* dstLine   = dst;
125
128k
  const Pel* srcLine   = src;
126
128k
  const Pel* bndryLine = bndry;
127
128
3.28M
  for( SizeType idxOrthDim = 0; idxOrthDim < outWidth; idxOrthDim++ )
129
3.16M
  {
130
3.16M
    const Pel* before  = bndryLine;
131
3.16M
    const Pel* behind  = srcLine;
132
3.16M
          Pel* currDst = dstLine;
133
28.4M
    for( SizeType idxUpsmpDim = 0; idxUpsmpDim < inHeight; idxUpsmpDim++ )
134
25.2M
    {
135
25.2M
      const int valDiff   = *behind - *before;
136
25.2M
            int scaledVal = ( ( *before ) << log2UpsmpFactor ) + roundingOffset;
137
138
126M
      for( SizeType pos = 0; pos < upsmpFactor; pos++)
139
101M
      {
140
101M
        scaledVal += valDiff;
141
101M
        *currDst   = scaledVal >> log2UpsmpFactor;
142
101M
        currDst += outWidth;
143
101M
      }
144
25.2M
      before = behind;
145
25.2M
      behind += srcStep;
146
25.2M
    }
147
148
3.16M
    srcLine ++;
149
3.16M
    dstLine ++;
150
3.16M
    bndryLine ++;
151
3.16M
  }
152
128k
}
Buffer.cpp:void vvenc::mipUpsampleVerCore<8u, 3u>(short*, short const*, short const*, unsigned int, unsigned int)
Line
Count
Source
120
90.1k
{
121
90.1k
  const int roundingOffset   = 1 << (log2UpsmpFactor - 1);
122
90.1k
  const SizeType upsmpFactor = 1 << log2UpsmpFactor;
123
124
90.1k
        Pel* dstLine   = dst;
125
90.1k
  const Pel* srcLine   = src;
126
90.1k
  const Pel* bndryLine = bndry;
127
128
5.85M
  for( SizeType idxOrthDim = 0; idxOrthDim < outWidth; idxOrthDim++ )
129
5.76M
  {
130
5.76M
    const Pel* before  = bndryLine;
131
5.76M
    const Pel* behind  = srcLine;
132
5.76M
          Pel* currDst = dstLine;
133
51.9M
    for( SizeType idxUpsmpDim = 0; idxUpsmpDim < inHeight; idxUpsmpDim++ )
134
46.1M
    {
135
46.1M
      const int valDiff   = *behind - *before;
136
46.1M
            int scaledVal = ( ( *before ) << log2UpsmpFactor ) + roundingOffset;
137
138
415M
      for( SizeType pos = 0; pos < upsmpFactor; pos++)
139
369M
      {
140
369M
        scaledVal += valDiff;
141
369M
        *currDst   = scaledVal >> log2UpsmpFactor;
142
369M
        currDst += outWidth;
143
369M
      }
144
46.1M
      before = behind;
145
46.1M
      behind += srcStep;
146
46.1M
    }
147
148
5.76M
    srcLine ++;
149
5.76M
    dstLine ++;
150
5.76M
    bndryLine ++;
151
5.76M
  }
152
90.1k
}
153
154
static void mipUpsampleHorCore( Pel* dst, const Pel* src, const Pel* bndry, const SizeType dstStride, const SizeType bndryStep, const SizeType predSize, const unsigned log2Factor )
155
319k
{
156
319k
  if( predSize == 4 )
157
8.35k
  {
158
8.35k
    if     ( log2Factor == 1 ) mipUpsampleHorCore<4, 1>( dst, src, bndry, dstStride, bndryStep );
159
0
    else if( log2Factor == 2 ) mipUpsampleHorCore<4, 2>( dst, src, bndry, dstStride, bndryStep );
160
0
    else                       mipUpsampleHorCore<4, 3>( dst, src, bndry, dstStride, bndryStep );
161
8.35k
  }
162
311k
  else
163
311k
  {
164
311k
    if     ( log2Factor == 1 ) mipUpsampleHorCore<8, 1>( dst, src, bndry, dstStride, bndryStep );
165
213k
    else if( log2Factor == 2 ) mipUpsampleHorCore<8, 2>( dst, src, bndry, dstStride, bndryStep );
166
90.1k
    else                       mipUpsampleHorCore<8, 3>( dst, src, bndry, dstStride, bndryStep );
167
311k
  }
168
319k
}
169
170
static void mipUpsampleVerCore( Pel* dst, const Pel* src, const Pel* bndry, const SizeType outWidth, const SizeType srcStep, const SizeType inHeight, const unsigned log2Factor )
171
318k
{
172
318k
  if( inHeight == 4 )
173
8.35k
  {
174
8.35k
    if     ( log2Factor == 1 ) mipUpsampleVerCore<4, 1>( dst, src, bndry, outWidth, srcStep );
175
0
    else if( log2Factor == 2 ) mipUpsampleVerCore<4, 2>( dst, src, bndry, outWidth, srcStep );
176
0
    else                       mipUpsampleVerCore<4, 3>( dst, src, bndry, outWidth, srcStep );
177
8.35k
  }
178
309k
  else
179
309k
  {
180
309k
    if     ( log2Factor == 1 ) mipUpsampleVerCore<8, 1>( dst, src, bndry, outWidth, srcStep );
181
218k
    else if( log2Factor == 2 ) mipUpsampleVerCore<8, 2>( dst, src, bndry, outWidth, srcStep );
182
90.1k
    else                       mipUpsampleVerCore<8, 3>( dst, src, bndry, outWidth, srcStep );
183
309k
  }
184
318k
}
185
186
template< unsigned inputSize, unsigned outputSize >
187
void mipMatrixMulCore( Pel* res, const Pel* input, const uint8_t* weight, const int maxVal, const int inputOffset, bool transpose )
188
330k
{
189
330k
  Pel buffer[ outputSize*outputSize];
190
191
330k
  int sum = 0;
192
2.97M
  for( int i = 0; i < inputSize; i++ )
193
2.64M
  {
194
2.64M
    sum += input[i];
195
2.64M
  }
196
330k
  const int offset = (1 << (MIP_SHIFT_MATRIX - 1)) - MIP_OFFSET_MATRIX * sum + (inputOffset << MIP_SHIFT_MATRIX);
197
330k
  CHECK( inputSize != 4 * (inputSize >> 2), "Error, input size not divisible by four" );
198
199
330k
  Pel* mat = transpose ? buffer : res;
200
330k
  unsigned posRes = 0;
201
21.0M
  for( unsigned n = 0; n < outputSize*outputSize; n++ )
202
20.7M
  {
203
20.7M
    int tmp0 = input[0] * weight[0];
204
20.7M
    int tmp1 = input[1] * weight[1];
205
20.7M
    int tmp2 = input[2] * weight[2];
206
20.7M
    int tmp3 = input[3] * weight[3];
207
20.7M
    if( 8 == inputSize )
208
20.7M
    {
209
20.7M
      tmp0 += input[4] * weight[4];
210
20.7M
      tmp1 += input[5] * weight[5];
211
20.7M
      tmp2 += input[6] * weight[6];
212
20.7M
      tmp3 += input[7] * weight[7];
213
20.7M
    }
214
20.7M
    mat[posRes++] = Clip3<int>( 0, maxVal, ((tmp0 + tmp1 + tmp2 + tmp3 + offset) >> MIP_SHIFT_MATRIX) );
215
216
20.7M
    weight += inputSize;
217
20.7M
  }
218
219
330k
  if( transpose )
220
150k
  {
221
1.33M
    for( int j = 0; j < outputSize; j++ )
222
1.18M
    {
223
10.6M
      for( int i = 0; i < outputSize; i++ )
224
9.41M
      {
225
9.41M
        res[j * outputSize + i] = buffer[i * outputSize + j];
226
9.41M
      }
227
1.18M
    }
228
150k
  }
229
330k
}
Unexecuted instantiation: void vvenc::mipMatrixMulCore<4u, 4u>(short*, short const*, unsigned char const*, int, int, bool)
void vvenc::mipMatrixMulCore<8u, 4u>(short*, short const*, unsigned char const*, int, int, bool)
Line
Count
Source
188
8.35k
{
189
8.35k
  Pel buffer[ outputSize*outputSize];
190
191
8.35k
  int sum = 0;
192
75.1k
  for( int i = 0; i < inputSize; i++ )
193
66.8k
  {
194
66.8k
    sum += input[i];
195
66.8k
  }
196
8.35k
  const int offset = (1 << (MIP_SHIFT_MATRIX - 1)) - MIP_OFFSET_MATRIX * sum + (inputOffset << MIP_SHIFT_MATRIX);
197
8.35k
  CHECK( inputSize != 4 * (inputSize >> 2), "Error, input size not divisible by four" );
198
199
8.35k
  Pel* mat = transpose ? buffer : res;
200
8.35k
  unsigned posRes = 0;
201
141k
  for( unsigned n = 0; n < outputSize*outputSize; n++ )
202
133k
  {
203
133k
    int tmp0 = input[0] * weight[0];
204
133k
    int tmp1 = input[1] * weight[1];
205
133k
    int tmp2 = input[2] * weight[2];
206
133k
    int tmp3 = input[3] * weight[3];
207
133k
    if( 8 == inputSize )
208
133k
    {
209
133k
      tmp0 += input[4] * weight[4];
210
133k
      tmp1 += input[5] * weight[5];
211
133k
      tmp2 += input[6] * weight[6];
212
133k
      tmp3 += input[7] * weight[7];
213
133k
    }
214
133k
    mat[posRes++] = Clip3<int>( 0, maxVal, ((tmp0 + tmp1 + tmp2 + tmp3 + offset) >> MIP_SHIFT_MATRIX) );
215
216
133k
    weight += inputSize;
217
133k
  }
218
219
8.35k
  if( transpose )
220
4.17k
  {
221
20.8k
    for( int j = 0; j < outputSize; j++ )
222
16.7k
    {
223
83.5k
      for( int i = 0; i < outputSize; i++ )
224
66.8k
      {
225
66.8k
        res[j * outputSize + i] = buffer[i * outputSize + j];
226
66.8k
      }
227
16.7k
    }
228
4.17k
  }
229
8.35k
}
void vvenc::mipMatrixMulCore<8u, 8u>(short*, short const*, unsigned char const*, int, int, bool)
Line
Count
Source
188
322k
{
189
322k
  Pel buffer[ outputSize*outputSize];
190
191
322k
  int sum = 0;
192
2.89M
  for( int i = 0; i < inputSize; i++ )
193
2.57M
  {
194
2.57M
    sum += input[i];
195
2.57M
  }
196
322k
  const int offset = (1 << (MIP_SHIFT_MATRIX - 1)) - MIP_OFFSET_MATRIX * sum + (inputOffset << MIP_SHIFT_MATRIX);
197
322k
  CHECK( inputSize != 4 * (inputSize >> 2), "Error, input size not divisible by four" );
198
199
322k
  Pel* mat = transpose ? buffer : res;
200
322k
  unsigned posRes = 0;
201
20.9M
  for( unsigned n = 0; n < outputSize*outputSize; n++ )
202
20.6M
  {
203
20.6M
    int tmp0 = input[0] * weight[0];
204
20.6M
    int tmp1 = input[1] * weight[1];
205
20.6M
    int tmp2 = input[2] * weight[2];
206
20.6M
    int tmp3 = input[3] * weight[3];
207
20.6M
    if( 8 == inputSize )
208
20.6M
    {
209
20.6M
      tmp0 += input[4] * weight[4];
210
20.6M
      tmp1 += input[5] * weight[5];
211
20.6M
      tmp2 += input[6] * weight[6];
212
20.6M
      tmp3 += input[7] * weight[7];
213
20.6M
    }
214
20.6M
    mat[posRes++] = Clip3<int>( 0, maxVal, ((tmp0 + tmp1 + tmp2 + tmp3 + offset) >> MIP_SHIFT_MATRIX) );
215
216
20.6M
    weight += inputSize;
217
20.6M
  }
218
219
322k
  if( transpose )
220
146k
  {
221
1.31M
    for( int j = 0; j < outputSize; j++ )
222
1.16M
    {
223
10.5M
      for( int i = 0; i < outputSize; i++ )
224
9.34M
      {
225
9.34M
        res[j * outputSize + i] = buffer[i * outputSize + j];
226
9.34M
      }
227
1.16M
    }
228
146k
  }
229
322k
}
230
231
template< typename T >
232
void addAvgCore( const T* src1, int src1Stride, const T* src2, int src2Stride, T* dest, int dstStride, int width, int height, unsigned rshift, int offset, const ClpRng& clpRng )
233
0
{
234
0
#define ADD_AVG_CORE_OP( ADDR ) dest[ADDR] = ClipPel( rightShiftU( ( src1[ADDR] + src2[ADDR] + offset ), rshift ), clpRng )
235
0
#define ADD_AVG_CORE_INC    \
236
0
  src1 += src1Stride;       \
237
0
  src2 += src2Stride;       \
238
0
  dest +=  dstStride;       \
239
0
240
0
  SIZE_AWARE_PER_EL_OP( ADD_AVG_CORE_OP, ADD_AVG_CORE_INC );
241
242
0
#undef ADD_AVG_CORE_OP
243
0
#undef ADD_AVG_CORE_INC
244
0
}
245
246
template<typename T>
247
void addWeightedAvgCore( const T* src1, int src1Stride, const T* src2, int src2Stride, T* dest, int destStride, int width, int height, unsigned rshift, int offset, int w0, int w1, const ClpRng& clpRng )
248
0
{
249
0
#define ADD_WGHT_AVG_OP( ADDR ) dest[ADDR] = ClipPel( rightShiftU( ( src1[ADDR]*w0 + src2[ADDR]*w1 + offset ), rshift ), clpRng )
250
0
#define ADD_WGHT_AVG_INC     \
251
0
    src1 += src1Stride; \
252
0
    src2 += src2Stride; \
253
0
    dest += destStride; \
254
0
255
0
  SIZE_AWARE_PER_EL_OP( ADD_WGHT_AVG_OP, ADD_WGHT_AVG_INC );
256
257
0
#undef ADD_WGHT_AVG_OP
258
0
#undef ADD_WGHT_AVG_INC
259
0
}
260
261
template<typename T>
262
void subsCore( const T* src0, int src0Stride, const T* src1, int src1Stride, T* dest, int destStride, int width, int height )
263
1.00M
{
264
1.00M
#define SUBS_INC                \
265
1.00M
  dest += destStride;  \
266
1.00M
  src0 += src0Stride;  \
267
1.00M
  src1 += src1Stride;  \
268
1.00M
269
494M
#define SUBS_OP( ADDR ) dest[ADDR] = src0[ADDR] - src1[ADDR]
270
271
494M
  SIZE_AWARE_PER_EL_OP( SUBS_OP, SUBS_INC );
272
273
1.00M
#undef SUBS_OP
274
1.00M
#undef SUBS_INC
275
1.00M
}
276
277
void removeHighFreq(int16_t* dst, int dstStride, const int16_t* src, int srcStride, int width, int height)
278
0
{
279
0
#define REM_HF_INC  \
280
0
 src += srcStride; \
281
0
 dst += dstStride; \
282
0
283
0
#define REM_HF_OP( ADDR )      dst[ADDR] =             2 * dst[ADDR] - src[ADDR]
284
285
0
 SIZE_AWARE_PER_EL_OP(REM_HF_OP, REM_HF_INC);
286
287
0
#undef REM_HF_INC
288
0
#undef REM_HF_OP
289
0
#undef REM_HF_OP_CLIP
290
0
}
291
292
template<typename T>
293
void reconstructCore( const T* src1, int src1Stride, const T* src2, int src2Stride, T* dest, int dstStride, int width, int height, const ClpRng& clpRng )
294
10.9k
{
295
5.08M
#define RECO_CORE_OP( ADDR ) dest[ADDR] = ClipPel( src1[ADDR] + src2[ADDR], clpRng )
296
10.9k
#define RECO_CORE_INC     \
297
10.9k
  src1 += src1Stride;     \
298
10.9k
  src2 += src2Stride;     \
299
10.9k
  dest +=  dstStride;     \
300
10.9k
301
5.08M
  SIZE_AWARE_PER_EL_OP( RECO_CORE_OP, RECO_CORE_INC );
302
303
10.9k
#undef RECO_CORE_OP
304
10.9k
#undef RECO_CORE_INC
305
10.9k
}
306
307
template<typename T>
308
void recoCore( const T* src1, const T* src2, T* dest, int numSamples, const ClpRng& clpRng )
309
2.83M
{
310
446M
  for( int n = 0; n < numSamples; n+=2)
311
444M
  {
312
444M
    dest[n]   = ClipPel( src1[n]   + src2[n], clpRng );
313
444M
    dest[n+1] = ClipPel( src1[n+1] + src2[n+1], clpRng );
314
444M
  }
315
2.83M
}
316
317
template<typename T>
318
void copyClipCore( const T* src, Pel* dst, int numSamples, const ClpRng& clpRng )
319
0
{
320
0
  for( int n = 0; n < numSamples; n+=2)
321
0
  {
322
0
    dst[n]   = ClipPel( src[n]   , clpRng );
323
0
    dst[n+1] = ClipPel( src[n+1] , clpRng );
324
0
  }
325
0
}
326
327
template< typename T >
328
void addAvgCore( const T* src1, const T* src2, T* dest, int numSamples, unsigned rshift, int offset, const ClpRng& clpRng )
329
0
{
330
0
  for( int n = 0; n < numSamples; n+=2)
331
0
  {
332
0
    dest[n]   = ClipPel( rightShiftU( ( src1[n]   + src2[n]   + offset ), rshift ), clpRng );
333
0
    dest[n+1] = ClipPel( rightShiftU( ( src1[n+1] + src2[n+1] + offset ), rshift ), clpRng );
334
0
  }
335
0
}
336
337
template< typename T >
338
void roundGeoCore( const T* src, T* dest, const int numSamples, unsigned rshift, int offset, const ClpRng &clpRng)
339
0
{
340
0
  for( int i = 0; i < numSamples; i+=2)
341
0
  {
342
0
    dest[i]   = ClipPel(rightShiftU(src[i  ] + offset, rshift), clpRng);
343
0
    dest[i+1] = ClipPel(rightShiftU(src[i+1] + offset, rshift), clpRng);
344
0
  }
345
0
}
346
347
template<typename T>
348
void linTfCore( const T* src, int srcStride, Pel* dst, int dstStride, int width, int height, int scale, unsigned shift, int offset, const ClpRng& clpRng, bool bClip )
349
258k
{
350
258k
#define LINTF_CORE_INC  \
351
258k
  src += srcStride;     \
352
258k
  dst += dstStride;     \
353
258k
354
258k
  if( bClip )
355
258k
  {
356
54.5M
#define LINTF_CORE_OP( ADDR ) dst[ADDR] = ( Pel ) ClipPel( rightShiftU( scale * src[ADDR], shift ) + offset, clpRng )
357
358
54.5M
  SIZE_AWARE_PER_EL_OP( LINTF_CORE_OP, LINTF_CORE_INC );
359
360
258k
#undef LINTF_CORE_OP
361
258k
  }
362
0
  else
363
0
  {
364
0
#define LINTF_CORE_OP( ADDR ) dst[ADDR] = ( Pel ) ( rightShiftU( scale * src[ADDR], shift ) + offset )
365
366
0
  SIZE_AWARE_PER_EL_OP( LINTF_CORE_OP, LINTF_CORE_INC );
367
368
0
#undef LINTF_CORE_OP
369
0
  }
370
258k
#undef LINTF_CORE_INC
371
258k
}
372
373
template<typename T, int N>
374
void transposeNxNCore( const Pel* src, int srcStride, Pel* dst, int dstStride )
375
9.55M
{
376
84.0M
  for( int i = 0; i < N; i++ )
377
74.5M
  {
378
662M
    for( int j = 0; j < N; j++ )
379
588M
    {
380
588M
      dst[j * dstStride] = src[j];
381
588M
    }
382
383
74.5M
    dst++;
384
74.5M
    src += srcStride;
385
74.5M
  }
386
9.55M
}
void vvenc::transposeNxNCore<short, 4>(short const*, int, short*, int)
Line
Count
Source
375
485k
{
376
2.42M
  for( int i = 0; i < N; i++ )
377
1.94M
  {
378
9.70M
    for( int j = 0; j < N; j++ )
379
7.76M
    {
380
7.76M
      dst[j * dstStride] = src[j];
381
7.76M
    }
382
383
1.94M
    dst++;
384
1.94M
    src += srcStride;
385
1.94M
  }
386
485k
}
void vvenc::transposeNxNCore<short, 8>(short const*, int, short*, int)
Line
Count
Source
375
9.07M
{
376
81.6M
  for( int i = 0; i < N; i++ )
377
72.5M
  {
378
653M
    for( int j = 0; j < N; j++ )
379
580M
    {
380
580M
      dst[j * dstStride] = src[j];
381
580M
    }
382
383
72.5M
    dst++;
384
72.5M
    src += srcStride;
385
72.5M
  }
386
9.07M
}
387
388
template<typename T>
389
void copyClipCore( const T* src, int srcStride, Pel* dst, int dstStride, int width, int height, const ClpRng& clpRng )
390
0
{
391
0
#define RECO_OP( ADDR ) dst[ADDR] = ClipPel( src[ADDR], clpRng )
392
0
#define RECO_INC      \
393
0
    src += srcStride; \
394
0
    dst += dstStride; \
395
0
396
0
  SIZE_AWARE_PER_EL_OP( RECO_OP, RECO_INC );
397
398
0
#undef RECO_OP
399
0
#undef RECO_INC
400
0
}
401
402
void copyBufferCore( const char* src, int srcStride, char* dst, int dstStride, int numBytes, int height)
403
10.8M
{
404
183M
  for( int i = 0; i < height; i++, src += srcStride, dst += dstStride )
405
172M
  {
406
172M
    memcpy( dst, src, numBytes );
407
172M
  }
408
10.8M
}
409
410
void fillMapPtr_Core( void** ptrMap, const ptrdiff_t mapStride, int width, int height, void* val )
411
562k
{
412
562k
  if( width == mapStride )
413
368k
  {
414
368k
    std::fill_n( ptrMap, width * height, val );
415
368k
  }
416
194k
  else
417
194k
  {
418
1.82M
    while( height-- )
419
1.63M
    {
420
1.63M
      std::fill_n( ptrMap, width, val );
421
1.63M
      ptrMap += mapStride;
422
1.63M
    }
423
194k
  }
424
562k
}
425
426
uint64_t AvgHighPassCore( const int width, const int height, const Pel* pSrc, const int iSrcStride)
427
14.0k
{
428
14.0k
  uint64_t saAct = 0;
429
1.16M
  for (int y = 1; y < height - 1; y++)
430
1.15M
  {
431
110M
    for (int x = 1; x < width - 1; x++) // center cols
432
109M
    {
433
109M
      const int s = 12 * (int) pSrc[x  ] - 2 * ((int) pSrc[x-1] + (int) pSrc[x+1] + (int) pSrc[x  -iSrcStride] + (int) pSrc[x  +iSrcStride])
434
109M
                             - ((int) pSrc[x-1-iSrcStride] + (int) pSrc[x+1-iSrcStride] + (int) pSrc[x-1+iSrcStride] + (int) pSrc[x+1+iSrcStride]);
435
109M
      saAct += abs (s);
436
109M
    }
437
1.15M
    pSrc += iSrcStride;
438
1.15M
  }
439
14.0k
  return saAct;
440
14.0k
}
441
442
uint64_t HDHighPassCore  (const int width, const int height,const Pel*  pSrc,const Pel* pSM1,const int iSrcStride,const int iSM1Stride)
443
0
{
444
0
  uint64_t taAct = 0;
445
0
  for (int y = 1; y < height - 1; y++)
446
0
  {
447
0
    for (int x = 1; x < width - 1; x++)  // cnt cols
448
0
    {
449
0
      const int t = (int) pSrc[x] - (int) pSM1[x];
450
0
      taAct += (1 + 3 * abs (t)) >> 1;
451
0
    }
452
0
    pSrc += iSrcStride;
453
0
    pSM1 += iSM1Stride;
454
0
  }
455
0
  return taAct;
456
0
}
457
458
uint64_t  HDHighPass2Core  (const int width, const int height,const Pel*  pSrc,const Pel* pSM1,const Pel* pSM2,const int iSrcStride,const int iSM1Stride,const int iSM2Stride)
459
0
{
460
0
  uint64_t taAct = 0;
461
0
  for (int y = 1; y < height - 1; y++)
462
0
  {
463
0
    for (int x = 1; x < width - 1; x++)  // cnt cols
464
0
    {
465
0
      const int t = (int) pSrc[x] - 2 * (int) pSM1[x] + (int) pSM2[x];
466
0
      taAct += abs (t);
467
0
    }
468
0
    pSrc += iSrcStride;
469
0
    pSM1 += iSM1Stride;
470
0
    pSM2 += iSM2Stride;
471
0
  }
472
0
  return taAct;
473
0
}
474
uint64_t AvgHighPassWithDownsamplingCore( const int width, const int height, const Pel* pSrc, const int iSrcStride)
475
0
{
476
0
  uint64_t saAct = 0;
477
0
  pSrc -= iSrcStride;
478
0
  pSrc -= iSrcStride;
479
0
 for (int y = 2; y < height - 2; y += 2)
480
0
 {
481
0
   for (int x = 2; x < width - 2; x += 2)
482
0
   {
483
0
     const int f = 12 * ((int)pSrc[ y   *iSrcStride + x  ] + (int)pSrc[ y   *iSrcStride + x+1] + (int)pSrc[(y+1)*iSrcStride + x  ] + (int)pSrc[(y+1)*iSrcStride + x+1])
484
0
                  - 3 * ((int)pSrc[(y-1)*iSrcStride + x  ] + (int)pSrc[(y-1)*iSrcStride + x+1] + (int)pSrc[(y+2)*iSrcStride + x  ] + (int)pSrc[(y+2)*iSrcStride + x+1])
485
0
                  - 3 * ((int)pSrc[ y   *iSrcStride + x-1] + (int)pSrc[ y   *iSrcStride + x+2] + (int)pSrc[(y+1)*iSrcStride + x-1] + (int)pSrc[(y+1)*iSrcStride + x+2])
486
0
                  - 2 * ((int)pSrc[(y-1)*iSrcStride + x-1] + (int)pSrc[(y-1)*iSrcStride + x+2] + (int)pSrc[(y+2)*iSrcStride + x-1] + (int)pSrc[(y+2)*iSrcStride + x+2])
487
0
                      - ((int)pSrc[(y-2)*iSrcStride + x-1] + (int)pSrc[(y-2)*iSrcStride + x  ] + (int)pSrc[(y-2)*iSrcStride + x+1] + (int)pSrc[(y-2)*iSrcStride + x+2]
488
0
                       + (int)pSrc[(y+3)*iSrcStride + x-1] + (int)pSrc[(y+3)*iSrcStride + x  ] + (int)pSrc[(y+3)*iSrcStride + x+1] + (int)pSrc[(y+3)*iSrcStride + x+2]
489
0
                       + (int)pSrc[(y-1)*iSrcStride + x-2] + (int)pSrc[ y   *iSrcStride + x-2] + (int)pSrc[(y+1)*iSrcStride + x-2] + (int)pSrc[(y+2)*iSrcStride + x-2]
490
0
                       + (int)pSrc[(y-1)*iSrcStride + x+3] + (int)pSrc[ y   *iSrcStride + x+3] + (int)pSrc[(y+1)*iSrcStride + x+3] + (int)pSrc[(y+2)*iSrcStride + x+3]);
491
0
     saAct += (uint64_t) abs(f);
492
0
   }
493
0
 }
494
0
 return saAct;
495
0
}
496
uint64_t AvgHighPassWithDownsamplingDiff1stCore (const int width, const int  height, const Pel* pSrc,const Pel* pSrcM1, const int iSrcStride, const int iSrcM1Stride)
497
0
{
498
0
  uint64_t taAct = 0;
499
0
  pSrc -= iSrcStride;
500
0
  pSrc -= iSrcStride;
501
0
  pSrcM1-=iSrcM1Stride;
502
0
  pSrcM1-=iSrcM1Stride;
503
504
0
  for (uint32_t y = 2; y < height-2; y += 2)
505
0
  {
506
0
    for (uint32_t x = 2; x < width-2; x += 2)
507
0
    {
508
0
      const int t = (int)pSrc  [y*iSrcStride + x] + (int)pSrc  [y*iSrcStride + x+1] + (int)pSrc  [(y+1)*iSrcStride + x] + (int)pSrc  [(y+1)*iSrcStride + x+1]
509
0
                 - ((int)pSrcM1[y*iSrcM1Stride + x] + (int)pSrcM1[y*iSrcM1Stride + x+1] + (int)pSrcM1[(y+1)*iSrcM1Stride + x] + (int)pSrcM1[(y+1)*iSrcM1Stride + x+1]);
510
0
      taAct += (1 + 3 * abs (t)) >> 1;
511
0
    }
512
0
  }
513
0
  return (taAct );
514
0
}
515
516
uint64_t AvgHighPassWithDownsamplingDiff2ndCore (const int width,const int height,const Pel* pSrc,const Pel* pSrcM1,const Pel* pSrcM2,const int iSrcStride,const int iSM1Stride,const int iSM2Stride)
517
0
{
518
0
  uint64_t taAct = 0;
519
520
0
  pSrc -= iSrcStride;
521
0
  pSrc -= iSrcStride;
522
0
  pSrcM1-=iSM1Stride;
523
0
  pSrcM1-=iSM1Stride;
524
0
  pSrcM2-=iSM2Stride;
525
0
  pSrcM2-=iSM2Stride;
526
527
0
  for (uint32_t y = 2; y < height-2; y += 2)
528
0
  {
529
0
    for (uint32_t x = 2; x < width-2; x += 2)
530
0
    {
531
0
      const int t = (int)pSrc  [y*iSrcStride + x] + (int)pSrc  [y*iSrcStride + x+1] + (int)pSrc  [(y+1)*iSrcStride + x] + (int)pSrc  [(y+1)*iSrcStride + x+1]
532
0
                            - 2 * ((int)pSrcM1[y*iSM1Stride + x] + (int)pSrcM1[y*iSM1Stride + x+1] + (int)pSrcM1[(y+1)*iSM1Stride + x] + (int)pSrcM1[(y+1)*iSM1Stride + x+1])
533
0
                            + (int)pSrcM2[y*iSM2Stride + x] + (int)pSrcM2[y*iSM2Stride + x+1] + (int)pSrcM2[(y+1)*iSM2Stride + x] + (int)pSrcM2[(y+1)*iSM2Stride + x+1];
534
0
      taAct += (uint64_t) abs(t);
535
0
    }
536
0
  }
537
0
  return (taAct);
538
0
}
539
540
uint64_t sumSquaredErrorCore( const Pel* src0, const ptrdiff_t stride0, const Pel* src1, const ptrdiff_t stride1, const int width, const int height )
541
4.47k
{
542
4.47k
  uint64_t sum = 0;
543
480k
  for( int y = 0; y < height; y++, src0 += stride0, src1 += stride1 )
544
476k
  {
545
59.9M
    for( int x = 0; x < width; x++ )
546
59.4M
    {
547
59.4M
      const Intermediate_Int diff = src0[x] - src1[x];
548
59.4M
      sum += uint64_t( diff * diff );
549
59.4M
    }
550
476k
  }
551
4.47k
  return sum;
552
4.47k
}
553
554
static uint32_t pictureChecksumCore( const Pel* plane, const ptrdiff_t stride, const int width, const int height, const bool twoBytes )
555
0
{
556
0
  uint32_t checksum = 0;
557
0
  for( int y = 0; y < height; y++, plane += stride )
558
0
  {
559
0
    for( int x = 0; x < width; x++ )
560
0
    {
561
0
      const uint8_t xorMask = ( x & 0xff ) ^ ( y & 0xff ) ^ ( x >> 8 ) ^ ( y >> 8 );
562
0
      checksum += ( plane[x] & 0xff ) ^ xorMask;
563
0
      if( twoBytes )
564
0
      {
565
0
        checksum += ( plane[x] >> 8 ) ^ xorMask;
566
0
      }
567
0
    }
568
0
  }
569
0
  return checksum;
570
0
}
571
572
static int64_t sumCore( const Pel* src, const ptrdiff_t stride, const int width, const int height )
573
33.2k
{
574
33.2k
  int64_t sum = 0;
575
1.89M
  for( int y = 0; y < height; y++, src += stride )
576
1.85M
  {
577
140M
    for( int x = 0; x < width; x++ )
578
138M
    {
579
138M
      sum += src[x];
580
138M
    }
581
1.85M
  }
582
33.2k
  return sum;
583
33.2k
}
584
585
static void sumAndSumSquaresCore( const Pel* src, const ptrdiff_t stride, const int width, const int height, int64_t& sum, int64_t& sumSquares )
586
0
{
587
0
  sum        = 0;
588
0
  sumSquares = 0;
589
0
  for( int y = 0; y < height; y++, src += stride )
590
0
  {
591
0
    for( int x = 0; x < width; x++ )
592
0
    {
593
0
      sum        += src[x];
594
0
      sumSquares += src[x] * src[x];
595
0
    }
596
0
  }
597
0
}
598
599
static void padHorizontalCore( Pel* src, const ptrdiff_t stride, const int width, const int height, const int marginLeft, const int marginRight )
600
36.7k
{
601
2.34M
  for( int y = 0; y < height; y++, src += stride )
602
2.31M
  {
603
46.2M
    for( int x = 0; x < marginLeft; x++ )
604
43.8M
    {
605
43.8M
      src[x - marginLeft] = src[0];
606
43.8M
    }
607
53.7M
    for( int x = 0; x < marginRight; x++ )
608
51.4M
    {
609
51.4M
      src[width + x] = src[width - 1];
610
51.4M
    }
611
2.31M
  }
612
36.7k
}
613
614
static void downsample2x2Core( const Pel* src, const ptrdiff_t srcStride, Pel* dst, const ptrdiff_t dstStride, const int dstWidth, const int dstHeight )
615
0
{
616
0
  for( int y = 0; y < dstHeight; y++, src += 2 * srcStride, dst += dstStride )
617
0
  {
618
0
    const Pel* below = src + srcStride;
619
0
    for( int x = 0; x < dstWidth; x++ )
620
0
    {
621
0
      dst[x] = Pel( ( src[2 * x] + below[2 * x] + src[2 * x + 1] + below[2 * x + 1] + 2 ) >> 2 );
622
0
    }
623
0
  }
624
0
}
625
626
int64_t highPassCorrelationCore( const Pel* cb, const ptrdiff_t cbStride, const Pel* cr, const ptrdiff_t crStride, const int width, const int height, const int bitDepth )
627
1.49k
{
628
1.49k
  int64_t sum = 0;
629
117k
  for( int y = 0; y < height; y++, cb += cbStride, cr += crStride )
630
116k
  {
631
9.56M
    for( int x = 0; x < width; x++ )
632
9.44M
    {
633
9.44M
      const int hpCb = ( 12*(int)cb[x] - 2*((int)cb[x-1] + (int)cb[x+1] + (int)cb[x-cbStride] + (int)cb[x+cbStride]) - ((int)cb[x-1-cbStride] + (int)cb[x+1-cbStride] + (int)cb[x-1+cbStride] + (int)cb[x+1+cbStride]) );
634
9.44M
      const int hpCr = ( 12*(int)cr[x] - 2*((int)cr[x-1] + (int)cr[x+1] + (int)cr[x-crStride] + (int)cr[x+crStride]) - ((int)cr[x-1-crStride] + (int)cr[x+1-crStride] + (int)cr[x-1+crStride] + (int)cr[x+1+crStride]) );
635
9.44M
      sum += hpCb * hpCr;
636
9.44M
    }
637
116k
  }
638
1.49k
  return sum;
639
1.49k
}
640
641
void blockStats4x4Core( const Pel* src, const ptrdiff_t stride, const int numBlocks, const int bitDepth, int* sum, int* absDev )
642
59.5k
{
643
2.53M
  for( int b = 0; b < numBlocks; b++, src += 4 )
644
2.47M
  {
645
2.47M
    int s = 0;
646
12.3M
    for( int h = 0; h < 4; h++ )
647
9.90M
    {
648
49.5M
      for( int w = 0; w < 4; w++ )
649
39.6M
      {
650
39.6M
        s += src[h * stride + w];
651
39.6M
      }
652
9.90M
    }
653
2.47M
    int d = 0;
654
12.3M
    for( int h = 0; h < 4; h++ )
655
9.90M
    {
656
49.5M
      for( int w = 0; w < 4; w++ )
657
39.6M
      {
658
39.6M
        d += abs( s - ( int( src[h * stride + w] ) << 4 ) );
659
39.6M
      }
660
9.90M
    }
661
2.47M
    sum[b]    = s;
662
2.47M
    absDev[b] = d;
663
2.47M
  }
664
59.5k
}
665
666
void absGradientSumsCore( const Pel* src, const ptrdiff_t stride, const int width, const int height, int* sums )
667
37.2k
{
668
37.2k
  Intermediate_Int horVal = 0;
669
37.2k
  Intermediate_Int verVal = 0;
670
37.2k
  Intermediate_Int dowVal = 0;
671
37.2k
  Intermediate_Int dupVal = 0;
672
673
3.00M
  for( int k = 0; k < height - 1; k++, src += stride )
674
2.96M
  {
675
2.96M
    const Pel* below = src + stride;
676
270M
    for( int j = 0; j < width - 1; j++ )
677
267M
    {
678
267M
      horVal += abs( src[j + 1]   - src[j] );
679
267M
      verVal += abs( below[j]     - src[j] );
680
267M
      dowVal += abs( src[j + 1]   - below[j] );
681
267M
      dupVal += abs( below[j + 1] - src[j] );
682
267M
    }
683
2.96M
  }
684
37.2k
  sums[0] = horVal;
685
37.2k
  sums[1] = verVal;
686
37.2k
  sums[2] = dowVal;
687
37.2k
  sums[3] = dupVal;
688
37.2k
}
689
690
static uint32_t sumAbsDeviationCore( const Pel* src, const ptrdiff_t stride, const int width, const int height, const int value )
691
0
{
692
0
  uint32_t sum = 0;
693
0
  for( int y = 0; y < height; y++, src += stride )
694
0
  {
695
0
    for( int x = 0; x < width; x++ )
696
0
    {
697
0
      sum += uint32_t( abs( src[x] - value ) );
698
0
    }
699
0
  }
700
0
  return sum;
701
0
}
702
703
PelBufferOps::PelBufferOps()
704
14
{
705
14
  addAvg            = addAvgCore<Pel>;
706
14
  reco              = recoCore<Pel>;
707
14
  copyClip          = copyClipCore<Pel>;
708
14
  roundGeo          = roundGeoCore<Pel>;
709
710
14
  addAvg4           = addAvgCore<Pel>;
711
14
  addAvg8           = addAvgCore<Pel>;
712
14
  addAvg16          = addAvgCore<Pel>;
713
714
14
  sub2              = subsCore<Pel>;
715
14
  sub4              = subsCore<Pel>;
716
14
  sub8              = subsCore<Pel>;
717
718
14
  wghtAvg4          = addWeightedAvgCore<Pel>;
719
14
  wghtAvg8          = addWeightedAvgCore<Pel>;
720
721
14
  copyClip2         = copyClipCore<Pel>;
722
14
  copyClip4         = copyClipCore<Pel>;
723
14
  copyClip8         = copyClipCore<Pel>;
724
725
14
  reco2             = reconstructCore<Pel>;
726
14
  reco4             = reconstructCore<Pel>;
727
14
  reco8             = reconstructCore<Pel>;
728
729
14
  linTf4            = linTfCore<Pel>;
730
14
  linTf8            = linTfCore<Pel>;
731
732
14
  copyBuffer        = copyBufferCore;
733
734
14
  removeHighFreq8   = removeHighFreq;
735
14
  removeHighFreq4   = removeHighFreq;
736
737
14
  transpose4x4      = transposeNxNCore<Pel,4>;
738
14
  transpose8x8      = transposeNxNCore<Pel,8>;
739
14
  mipMatrixMul_4_4  = mipMatrixMulCore<4,4>;
740
14
  mipMatrixMul_8_4  = mipMatrixMulCore<8,4>;
741
14
  mipMatrixMul_8_8  = mipMatrixMulCore<8,8>;
742
14
  mipUpsampleHor    = mipUpsampleHorCore;
743
14
  mipUpsampleVer    = mipUpsampleVerCore;
744
14
  weightCiip        = weightCiipCore;
745
14
  roundIntVector    = nullptr;
746
747
14
  fillPtrMap        = fillMapPtr_Core;
748
14
  AvgHighPassWithDownsampling = AvgHighPassWithDownsamplingCore;
749
14
  AvgHighPass = AvgHighPassCore;
750
14
  AvgHighPassWithDownsamplingDiff1st = AvgHighPassWithDownsamplingDiff1stCore;
751
14
  AvgHighPassWithDownsamplingDiff2nd = AvgHighPassWithDownsamplingDiff2ndCore;
752
14
  HDHighPass = HDHighPassCore;
753
14
  HDHighPass2 = HDHighPass2Core;
754
14
  sumSquaredError  = sumSquaredErrorCore;
755
14
  sum              = sumCore;
756
14
  sumAndSumSquares = sumAndSumSquaresCore;
757
14
  pictureChecksum  = pictureChecksumCore;
758
14
  padHorizontal    = padHorizontalCore;
759
14
  downsample2x2    = downsample2x2Core;
760
14
  highPassCorrelation = highPassCorrelationCore;
761
14
  blockStats4x4       = blockStats4x4Core;
762
14
  absGradientSums     = absGradientSumsCore;
763
14
  sumAbsDeviation     = sumAbsDeviationCore;
764
14
}
765
766
void PelBufferOps::initPelBufOps( bool enableOpt )
767
0
{
768
0
  if( isInitSIMDDone )
769
0
  {
770
0
    return;
771
0
  }
772
0
  isInitSIMDDone = true;
773
774
0
  if( enableOpt )
775
0
  {
776
0
#if ENABLE_SIMD_OPT_BUFFER
777
#  if defined( TARGET_SIMD_X86 )
778
    initPelBufOpsX86();
779
#  endif
780
#  if defined( TARGET_SIMD_ARM )
781
    initPelBufOpsARM();
782
#  endif
783
0
#endif   // ENABLE_SIMD_OPT_BUFFER
784
0
  }
785
0
}
786
787
PelBufferOps g_pelBufOP = PelBufferOps();
788
789
template<>
790
Pel AreaBuf<Pel>::getAvg() const
791
1.49k
{
792
1.49k
  return Pel( ( g_pelBufOP.sum( buf, stride, width, height ) + ( area() >> 1 ) ) / area() );
793
1.49k
}
794
795
template<>
796
const Pel AreaBuf<const Pel>::getAvg() const
797
31.7k
{
798
31.7k
  return Pel( ( g_pelBufOP.sum( buf, stride, width, height ) + ( area() >> 1 ) ) / area() );
799
31.7k
}
800
801
template<>
802
void AreaBuf<Pel>::extendBorderPelLft( int y, int size, int margin )
803
16.1k
{
804
16.1k
  g_pelBufOP.padHorizontal( buf + y * stride, stride, width, size, margin, 0 );
805
16.1k
}
806
807
template<>
808
void AreaBuf<Pel>::extendBorderPelRgt( int y, int size, int margin )
809
16.1k
{
810
16.1k
  g_pelBufOP.padHorizontal( buf + y * stride, stride, width, size, 0, margin );
811
16.1k
}
812
813
template<>
814
void AreaBuf<Pel>::extendBorderPel( unsigned marginX, unsigned marginY )
815
4.47k
{
816
4.47k
  CHECK( ( width + 2 * marginX ) > stride, "Size of buffer too small to extend" );
817
818
  // left and right margins
819
4.47k
  g_pelBufOP.padHorizontal( buf, stride, width, height, marginX, marginX );
820
821
  // top and bottom margins, copied from the extended first and last row
822
4.47k
  Pel* firstRow = buf - marginX;
823
4.47k
  Pel* lastRow  = buf - marginX + ( height - 1 ) * stride;
824
4.47k
  const size_t rowSize = sizeof( Pel ) * ( width + ( marginX << 1 ) );
825
52.2k
  for( unsigned y = 0; y < marginY; y++ )
826
47.7k
  {
827
47.7k
    ::memcpy( lastRow + ( y + 1 ) * stride, lastRow, rowSize );
828
47.7k
  }
829
52.2k
  for( unsigned y = 0; y < marginY; y++ )
830
47.7k
  {
831
47.7k
    ::memcpy( firstRow - ( y + 1 ) * stride, firstRow, rowSize );
832
47.7k
  }
833
4.47k
}
834
835
template<>
836
void AreaBuf<Pel>::addWeightedAvg(const AreaBuf<const Pel>& other1, const AreaBuf<const Pel>& other2, const ClpRng& clpRng, const int8_t BcwIdx)
837
0
{
838
0
  const int8_t w0 = getBcwWeight( BcwIdx, REF_PIC_LIST_0 );
839
0
  const int8_t w1 = getBcwWeight( BcwIdx, REF_PIC_LIST_1 );
840
0
  const int8_t log2WeightBase = g_BcwLog2WeightBase;
841
0
  const Pel* src0 = other1.buf;
842
0
  const Pel* src2 = other2.buf;
843
0
        Pel* dest =        buf;
844
845
0
  const int src1Stride = other1.stride;
846
0
  const int src2Stride = other2.stride;
847
0
  const int destStride =        stride;
848
0
  const int clipbd     = clpRng.bd;
849
0
  const int shiftNum   = std::max<int>( 2, ( IF_INTERNAL_PREC - clipbd ) ) + log2WeightBase;
850
0
  const int offset     = ( 1 << ( shiftNum - 1 ) ) + ( IF_INTERNAL_OFFS << log2WeightBase );
851
852
0
  if( ( width & 7 ) == 0 )
853
0
  {
854
0
    g_pelBufOP.wghtAvg8( src0, src1Stride, src2, src2Stride, dest, destStride, width, height, shiftNum, offset, w0, w1, clpRng );
855
0
  }
856
0
  else if( ( width & 3 ) == 0 )
857
0
  {
858
0
    g_pelBufOP.wghtAvg4( src0, src1Stride, src2, src2Stride, dest, destStride, width, height, shiftNum, offset, w0, w1, clpRng );
859
0
  }
860
0
  else
861
0
  {
862
0
#define WGHT_AVG_OP( ADDR ) dest[ADDR] = ClipPel( rightShiftU( ( src0[ADDR]*w0 + src2[ADDR]*w1 + offset ), shiftNum ), clpRng )
863
0
#define WGHT_AVG_INC    \
864
0
    src0 += src1Stride; \
865
0
    src2 += src2Stride; \
866
0
    dest += destStride; \
867
0
868
0
    SIZE_AWARE_PER_EL_OP( WGHT_AVG_OP, WGHT_AVG_INC );
869
870
0
#undef WGHT_AVG_OP
871
0
#undef WGHT_AVG_INC
872
0
  }
873
0
}
874
875
template<>
876
void AreaBuf<Pel>::addAvg( const AreaBuf<const Pel>& other1, const AreaBuf<const Pel>& other2, const ClpRng& clpRng)
877
0
{
878
0
  const Pel* src0 = other1.buf;
879
0
  const Pel* src2 = other2.buf;
880
0
        Pel* dest =        buf;
881
882
0
  const unsigned src1Stride = other1.stride;
883
0
  const unsigned src2Stride = other2.stride;
884
0
  const unsigned destStride =        stride;
885
0
  const int      clipbd     = clpRng.bd;
886
0
  const unsigned shiftNum   = std::max<int>(2, (IF_INTERNAL_PREC - clipbd)) + 1;
887
0
  const int      offset     = (1 << (shiftNum - 1)) + 2 * IF_INTERNAL_OFFS;
888
889
0
#if ENABLE_SIMD_OPT_BUFFER
890
0
  if( destStride == width )
891
0
  {
892
0
    g_pelBufOP.addAvg(src0, src2, dest, width * height, shiftNum, offset, clpRng);
893
0
  }
894
0
  else if ((width & 15) == 0)
895
0
  {
896
0
    g_pelBufOP.addAvg16(src0, src1Stride, src2, src2Stride, dest, destStride, width, height, shiftNum, offset, clpRng);
897
0
  }
898
0
  else if( ( width & 7 ) == 0 )
899
0
  {
900
0
    g_pelBufOP.addAvg8( src0, src1Stride, src2, src2Stride, dest, destStride, width, height, shiftNum, offset, clpRng );
901
0
  }
902
0
  else if( ( width & 3 ) == 0 )
903
0
  {
904
0
    g_pelBufOP.addAvg4( src0, src1Stride, src2, src2Stride, dest, destStride, width, height, shiftNum, offset, clpRng );
905
0
  }
906
0
  else
907
0
#endif
908
0
  {
909
0
#define ADD_AVG_OP( ADDR ) dest[ADDR] = ClipPel( rightShiftU( ( src0[ADDR] + src2[ADDR] + offset ), shiftNum ), clpRng )
910
0
#define ADD_AVG_INC     \
911
0
    src0 += src1Stride; \
912
0
    src2 += src2Stride; \
913
0
    dest += destStride; \
914
0
915
0
    SIZE_AWARE_PER_EL_OP( ADD_AVG_OP, ADD_AVG_INC );
916
917
0
#undef ADD_AVG_OP
918
0
#undef ADD_AVG_INC
919
0
  }
920
0
}
921
922
template<>
923
void AreaBuf<Pel>::subtract( const AreaBuf<const Pel>& minuend, const AreaBuf<const Pel>& subtrahend )
924
1.00M
{
925
1.00M
  CHECKD( width  != minuend.width,     "Incompatible size" );
926
1.00M
  CHECKD( height != minuend.height,    "Incompatible size" );
927
1.00M
  CHECKD( width  != subtrahend.width,  "Incompatible size");
928
1.00M
  CHECKD( height != subtrahend.height, "Incompatible size");
929
  
930
1.00M
        Pel* dest =            buf;
931
1.00M
  const Pel* mins = minuend   .buf;
932
1.00M
  const Pel* subs = subtrahend.buf;
933
934
935
1.00M
#if ENABLE_SIMD_OPT_BUFFER
936
1.00M
  const unsigned destStride =            stride;
937
1.00M
  const unsigned minsStride = minuend.   stride;
938
1.00M
  const unsigned subsStride = subtrahend.stride;
939
940
1.00M
  if( ( width & 7 ) == 0 )
941
857k
  {
942
857k
    g_pelBufOP.sub8( mins, minsStride, subs, subsStride, dest, destStride, width, height );
943
857k
  }
944
151k
  else if( ( width & 3 ) == 0 )
945
151k
  {
946
151k
    g_pelBufOP.sub4( mins, minsStride, subs, subsStride, dest, destStride, width, height );
947
151k
  }
948
0
  else if( width == 2 )
949
0
  {
950
0
    g_pelBufOP.sub2( mins, minsStride, subs, subsStride, dest, destStride, width, height );
951
0
  }
952
0
  else
953
0
#endif
954
0
  {
955
0
#define SUBS_INC                \
956
0
    dest +=            stride;  \
957
0
    mins += minuend   .stride;  \
958
0
    subs += subtrahend.stride;  \
959
0
960
0
#define SUBS_OP( ADDR ) dest[ADDR] = mins[ADDR] - subs[ADDR]
961
962
0
    SIZE_AWARE_PER_EL_OP( SUBS_OP, SUBS_INC );
963
964
0
#undef SUBS_OP
965
0
#undef SUBS_INC
966
0
  }
967
1.00M
}
968
969
template<>
970
void AreaBuf<const Pel>::calcVarianceSplit( const AreaBuf<const Pel>& Org, const uint32_t  size, int& varh,int& varv) const
971
0
{
972
0
  CHECK( Org.width != Org.height, "Incompatible size!" );
973
0
  int stride = Org.stride;
974
0
  double variance=0;
975
0
  double mean=0;
976
0
  int64_t sum[4]={0,0,0,0};
977
0
  int64_t sum_sqr[4]={0,0,0,0};
978
0
  uint32_t halfsize =size>>1;
979
0
  uint32_t off[4]={0,halfsize,size*halfsize,size*halfsize+halfsize};
980
981
0
  for( int n = 0; n < 4; n++ )
982
0
  {
983
0
    g_pelBufOP.sumAndSumSquares( Org.buf + off[n], stride, halfsize, halfsize, sum[n], sum_sqr[n] );
984
0
  }
985
0
  int num=size*(size>>1);
986
  // varhu
987
0
  mean=(double)(sum[0]+sum[1])/(num);
988
0
  variance =  (double)(sum_sqr[0]+sum_sqr[1])/(num) - (mean*mean);
989
0
  varh =(int)(variance+0.5);
990
  // varhl
991
0
  mean=(double)(sum[2]+sum[3])/(num);
992
0
  variance =  (double)(sum_sqr[2]+sum_sqr[3])/(num) - (mean*mean);
993
0
  varh +=(int)(variance+0.5);
994
  // varvl
995
0
  mean=(double)(sum[0]+sum[2])/(num);
996
0
  variance =  (double)(sum_sqr[0]+sum_sqr[2])/(num) - (mean*mean);
997
0
  varv =(int)(variance+0.5);
998
  // varvr
999
0
  mean=(double)(sum[1]+sum[3])/(num);
1000
0
  variance =  (double)(sum_sqr[1]+sum_sqr[3])/(num) - (mean*mean);
1001
0
  varv +=(int)(variance+0.5);
1002
0
}
1003
1004
template<>
1005
void AreaBuf<Pel>::copyClip( const AreaBuf<const Pel>& src, const ClpRng& clpRng )
1006
0
{
1007
0
  const Pel* srcp = src.buf;
1008
0
        Pel* dest =     buf;
1009
1010
0
  const unsigned srcStride  = src.stride;
1011
0
  const unsigned destStride = stride;
1012
1013
0
  if( destStride == width)
1014
0
  {
1015
0
    g_pelBufOP.copyClip(srcp, dest, width * height, clpRng);
1016
0
  }
1017
0
  else if ((width & 7) == 0)
1018
0
  {
1019
0
    g_pelBufOP.copyClip8(srcp, srcStride, dest, destStride, width, height, clpRng);
1020
0
  }
1021
0
  else if ((width & 3) == 0)
1022
0
  {
1023
0
    g_pelBufOP.copyClip4(srcp, srcStride, dest, destStride, width, height, clpRng);
1024
0
  }
1025
0
  else if( height >= 8 )
1026
0
  {
1027
0
    CHECKD( width != 2, "Expecting width to be '2'!" );
1028
0
    g_pelBufOP.copyClip2( srcp, srcStride, dest, destStride, width, height, clpRng );
1029
0
  }
1030
0
  else
1031
0
  {
1032
    // for fewer rows this loop is faster than the call of copyClip2
1033
0
    CHECKD( width != 2, "Expecting width to be '2'!" );
1034
0
    for( int y = 0; y < height; y++ )
1035
0
    {
1036
0
      dest[0] = ClipPel( srcp[0], clpRng );
1037
0
      dest[1] = ClipPel( srcp[1], clpRng );
1038
0
      srcp += srcStride;
1039
0
      dest += destStride;
1040
0
    }
1041
0
  }
1042
0
}
1043
1044
template<>
1045
void AreaBuf<Pel>::reconstruct( const AreaBuf<const Pel>& pred, const AreaBuf<const Pel>& resi, const ClpRng& clpRng )
1046
2.84M
{
1047
2.84M
  const Pel* src1 = pred.buf;
1048
2.84M
  const Pel* src2 = resi.buf;
1049
2.84M
        Pel* dest =      buf;
1050
1051
2.84M
  const unsigned src1Stride = pred.stride;
1052
2.84M
  const unsigned src2Stride = resi.stride;
1053
2.84M
  const unsigned destStride =      stride;
1054
2.84M
  if( src2Stride == width )
1055
2.83M
  {
1056
2.83M
    g_pelBufOP.reco( pred.buf, resi.buf, buf, width * height, clpRng );
1057
2.83M
  }
1058
10.9k
  else if( ( width & 7 ) == 0 )
1059
7.18k
  {
1060
7.18k
    g_pelBufOP.reco8( src1, src1Stride, src2, src2Stride, dest, destStride, width, height, clpRng );
1061
7.18k
  }
1062
3.77k
  else if( ( width & 3 ) == 0 )
1063
3.77k
  {
1064
3.77k
    g_pelBufOP.reco4( src1, src1Stride, src2, src2Stride, dest, destStride, width, height, clpRng );
1065
3.77k
  }
1066
18.4E
  else if( width == 2 && height >= 8 )
1067
0
  {
1068
0
    g_pelBufOP.reco2( src1, src1Stride, src2, src2Stride, dest, destStride, width, height, clpRng );
1069
0
  }
1070
18.4E
  else if( ( width & 1 ) == 0 )
1071
0
  {
1072
    // for fewer rows this loop is faster than the call of reco2
1073
0
    for( int y = 0; y < height; y++ )
1074
0
    {
1075
0
      dest[0] = ClipPel( src1[0] + src2[0], clpRng );
1076
0
      dest[1] = ClipPel( src1[1] + src2[1], clpRng );
1077
0
      src1 += src1Stride;
1078
0
      src2 += src2Stride;
1079
0
      dest += destStride;
1080
0
    }
1081
0
  }
1082
18.4E
  else
1083
18.4E
  {
1084
18.4E
    CHECKD( width != 1, "Expecting width to be '1'!" );
1085
1086
18.4E
    for( int y = 0; y < height; y++ )
1087
0
    {
1088
0
      dest[0] = ClipPel( src1[0] + src2[0], clpRng );
1089
1090
0
      src1 += src1Stride;
1091
0
      src2 += src2Stride;
1092
0
      dest += destStride;
1093
0
    }
1094
18.4E
  }
1095
2.84M
}
1096
1097
template<>
1098
void AreaBuf<Pel>::linearTransform( const int scale, const unsigned shift, const int offset, bool bClip, const ClpRng& clpRng )
1099
258k
{
1100
258k
  const Pel* src = buf;
1101
258k
        Pel* dst = buf;
1102
1103
258k
  if( stride == width)
1104
258k
  {
1105
258k
    if( width > 2 && height > 2 )
1106
244k
    {
1107
244k
      g_pelBufOP.linTf8( src, stride<<2, dst, stride<<2, width<<2, height>>2, scale, shift, offset, clpRng, bClip );
1108
244k
    }
1109
14.8k
    else
1110
14.8k
    {
1111
14.8k
      g_pelBufOP.linTf4( src, stride<<1, dst, stride<<1, width<<1, height>>1, scale, shift, offset, clpRng, bClip );
1112
14.8k
    }
1113
258k
  }
1114
0
  else if( ( width & 7 ) == 0 )
1115
0
  {
1116
0
    g_pelBufOP.linTf8( src, stride, dst, stride, width, height, scale, shift, offset, clpRng, bClip );
1117
0
  }
1118
0
  else if( ( width & 3 ) == 0 )
1119
0
  {
1120
0
    g_pelBufOP.linTf4( src, stride, dst, stride, width, height, scale, shift, offset, clpRng, bClip );
1121
0
  }
1122
0
  else
1123
0
  {
1124
0
    if( bClip )
1125
0
    {
1126
0
      for( int y = 0; y < height; y++ )
1127
0
      {
1128
0
        dst[0] = ( Pel ) ClipPel( rightShiftU( scale * src[0], shift ) + offset, clpRng );
1129
0
        dst[1] = ( Pel ) ClipPel( rightShiftU( scale * src[1], shift ) + offset, clpRng );
1130
0
        src += stride;
1131
0
        dst += stride;
1132
0
      }
1133
0
    }
1134
0
    else
1135
0
    {
1136
0
      for( int y = 0; y < height; y++ )
1137
0
      {
1138
0
        dst[0] = ( Pel ) ( rightShiftU( scale * src[0], shift ) + offset );
1139
0
        dst[1] = ( Pel ) ( rightShiftU( scale * src[1], shift ) + offset );
1140
0
        src += stride;
1141
0
        dst += stride;
1142
0
      }
1143
0
    }
1144
0
  }
1145
258k
}
1146
1147
#if ENABLE_SIMD_OPT_BUFFER
1148
1149
template<>
1150
void AreaBuf<Pel>::transposedFrom( const AreaBuf<const Pel>& other )
1151
761k
{
1152
761k
  CHECK( width != other.height || height != other.width, "Incompatible size" );
1153
1154
761k
  if( ( ( width | height ) & 7 ) == 0 )
1155
620k
  {
1156
620k
    const Pel* src = other.buf;
1157
1158
2.56M
    for( unsigned y = 0; y < other.height; y += 8 )
1159
1.94M
    {
1160
1.94M
      Pel* dst = buf + y;
1161
1162
11.0M
      for( unsigned x = 0; x < other.width; x += 8 )
1163
9.07M
      {
1164
9.07M
        g_pelBufOP.transpose8x8( &src[x], other.stride, dst, stride );
1165
1166
9.07M
        dst += 8 * stride;
1167
9.07M
      }
1168
1169
1.94M
      src += 8 * other.stride;
1170
1.94M
    }
1171
620k
  }
1172
140k
  else if( ( ( width | height ) & 3 ) == 0 )
1173
128k
  {
1174
128k
    const Pel* src = other.buf;
1175
1176
382k
    for( unsigned y = 0; y < other.height; y += 4 )
1177
253k
    {
1178
253k
      Pel* dst = buf + y;
1179
1180
738k
      for( unsigned x = 0; x < other.width; x += 4 )
1181
485k
      {
1182
485k
        g_pelBufOP.transpose4x4( &src[x], other.stride, dst, stride );
1183
1184
485k
        dst += 4 * stride;
1185
485k
      }
1186
1187
253k
      src += 4 * other.stride;
1188
253k
    }
1189
128k
  }
1190
12.0k
  else
1191
12.0k
  {
1192
12.0k
          Pel* dst =       buf;
1193
12.0k
    const Pel* src = other.buf;
1194
12.0k
    width          = other.height;
1195
12.0k
    height         = other.width;
1196
12.0k
    stride         = stride < width ? width : stride;
1197
1198
148k
    for( unsigned y = 0; y < other.height; y++ )
1199
136k
    {
1200
410k
      for( unsigned x = 0; x < other.width; x++ )
1201
273k
      {
1202
273k
        dst[y + x*stride] = src[x + y * other.stride];
1203
273k
      }
1204
136k
    }
1205
12.0k
  }
1206
761k
}
1207
#endif
1208
1209
template<>
1210
void AreaBuf<Pel>::weightCiip( const AreaBuf<const Pel>& intra, const int numIntra )
1211
0
{
1212
0
  CHECK(width == 2, "Width of 2 is not supported");
1213
0
  g_pelBufOP.weightCiip( buf, intra.buf, width * height, numIntra );
1214
0
}
1215
1216
template<>
1217
void AreaBuf<MotionInfo>::fill( const MotionInfo& val )
1218
29.1k
{
1219
29.1k
  if( width == stride )
1220
29.1k
  {
1221
29.1k
    std::fill_n( buf, width * height, val );
1222
29.1k
  }
1223
0
  else
1224
0
  {
1225
0
    MotionInfo* dst = buf;
1226
1227
0
    for( int y = 0; y < height; y++, dst += stride )
1228
0
    {
1229
0
      std::fill_n( dst, width, val );
1230
0
    }
1231
0
  }
1232
29.1k
}
1233
1234
PelStorage::PelStorage()
1235
1.06M
{
1236
4.24M
  for( uint32_t i = 0; i < MAX_NUM_COMP; i++ )
1237
3.18M
  {
1238
3.18M
    m_origin[i] = nullptr;
1239
3.18M
  }
1240
1.06M
}
1241
1242
PelStorage::~PelStorage()
1243
1.06M
{
1244
1.06M
  destroy();
1245
1.06M
}
1246
1247
void PelStorage::create( const UnitArea& _UnitArea )
1248
561k
{
1249
561k
  create( _UnitArea.chromaFormat, _UnitArea.blocks[0] );
1250
561k
  m_maxArea = _UnitArea;
1251
561k
}
1252
1253
void PelStorage::create( const ChromaFormat &_chromaFormat, const Area& _area )
1254
877k
{
1255
877k
  CHECK( !bufs.empty(), "Trying to re-create an already initialized buffer" );
1256
1257
877k
  chromaFormat = _chromaFormat;
1258
1259
877k
  const uint32_t numComp = getNumberValidComponents( _chromaFormat );
1260
1261
877k
  uint32_t bufSize = 0;
1262
3.51M
  for( uint32_t i = 0; i < numComp; i++ )
1263
2.63M
  {
1264
2.63M
    const ComponentID compID = ComponentID( i );
1265
2.63M
    const unsigned totalWidth  = _area.width  >> getComponentScaleX( compID, _chromaFormat );
1266
2.63M
    const unsigned totalHeight = _area.height >> getComponentScaleY( compID, _chromaFormat );
1267
1268
2.63M
    const uint32_t area = totalWidth * totalHeight;
1269
2.63M
    CHECK( !area, "Trying to create a buffer with zero area" );
1270
2.63M
    bufSize += area;
1271
2.63M
  }
1272
1273
877k
  bufSize += 1; // for SIMD DMVR on the bottom right corner, which overreads the lines by 1 sample
1274
1275
  //allocate one buffer
1276
877k
  m_origin[0] = ( Pel* ) xMalloc( Pel, bufSize );
1277
1278
877k
  Pel* topLeft = m_origin[0];
1279
3.51M
  for( uint32_t i = 0; i < numComp; i++ )
1280
2.63M
  {
1281
2.63M
    const ComponentID compID = ComponentID( i );
1282
2.63M
    const unsigned totalWidth  = _area.width  >> getComponentScaleX( compID, _chromaFormat );
1283
2.63M
    const unsigned totalHeight = _area.height >> getComponentScaleY( compID, _chromaFormat );
1284
2.63M
    const uint32_t area = totalWidth * totalHeight;
1285
1286
2.63M
    bufs.push_back( PelBuf( topLeft, totalWidth, totalWidth, totalHeight ) );
1287
2.63M
    topLeft += area;
1288
2.63M
  }
1289
1290
877k
  m_maxArea = UnitArea( _chromaFormat, _area );
1291
877k
}
1292
1293
void PelStorage::create( const ChromaFormat &_chromaFormat, const Area& _area, const unsigned _maxCUSize, const unsigned _margin, const unsigned _alignment, const bool _scaleChromaMargin )
1294
68.6k
{
1295
68.6k
  CHECK( !bufs.empty(), "Trying to re-create an already initialized buffer" );
1296
1297
68.6k
  chromaFormat = _chromaFormat;
1298
1299
68.6k
  const uint32_t numComp = getNumberValidComponents( _chromaFormat );
1300
1301
68.6k
  unsigned extHeight = _area.height;
1302
68.6k
  unsigned extWidth  = _area.width;
1303
1304
68.6k
  if( _maxCUSize )
1305
19.4k
  {
1306
19.4k
    extHeight = ( ( _area.height + _maxCUSize - 1 ) / _maxCUSize ) * _maxCUSize;
1307
19.4k
    extWidth  = ( ( _area.width  + _maxCUSize - 1 ) / _maxCUSize ) * _maxCUSize;
1308
19.4k
  }
1309
1310
250k
  for( uint32_t i = 0; i < numComp; i++ )
1311
182k
  {
1312
182k
    const ComponentID compID = ComponentID( i );
1313
182k
    const unsigned scaleX = getComponentScaleX( compID, _chromaFormat );
1314
182k
    const unsigned scaleY = getComponentScaleY( compID, _chromaFormat );
1315
1316
182k
    unsigned scaledHeight = extHeight >> scaleY;
1317
182k
    unsigned scaledWidth  = extWidth  >> scaleX;
1318
182k
    unsigned ymargin      = _margin >> (_scaleChromaMargin?scaleY:0);
1319
182k
    unsigned xmargin      = _margin >> (_scaleChromaMargin?scaleX:0);
1320
182k
    unsigned totalWidth   = scaledWidth + 2*xmargin;
1321
182k
    unsigned totalHeight  = scaledHeight +2*ymargin;
1322
1323
182k
    if( _alignment )
1324
76.1k
    {
1325
      // make sure buffer lines are align
1326
76.1k
      CHECK( _alignment != MEMORY_ALIGN_DEF_SIZE, "Unsupported alignment" );
1327
76.1k
      totalWidth = ( ( totalWidth + _alignment - 1 ) / _alignment ) * _alignment;
1328
76.1k
    }
1329
182k
    uint32_t area = totalWidth * totalHeight;
1330
182k
    CHECK( !area, "Trying to create a buffer with zero area" );
1331
1332
182k
    m_origin[i] = ( Pel* ) xMalloc( Pel, area );
1333
182k
    Pel* topLeft = m_origin[i] + totalWidth * ymargin + xmargin;
1334
182k
    bufs.push_back( PelBuf( topLeft, totalWidth, _area.width >> scaleX, _area.height >> scaleY ) );
1335
182k
  }
1336
1337
68.6k
  m_maxArea = UnitArea( _chromaFormat, _area );
1338
68.6k
}
1339
1340
void PelStorage::createFromBuf( PelUnitBuf buf )
1341
1.49k
{
1342
1.49k
  chromaFormat = buf.chromaFormat;
1343
1344
1.49k
  const uint32_t numCh = getNumberValidComponents( chromaFormat );
1345
1346
1.49k
  bufs.resize(numCh);
1347
1348
5.97k
  for( uint32_t i = 0; i < numCh; i++ )
1349
4.47k
  {
1350
4.47k
    PelBuf cPelBuf = buf.get( ComponentID( i ) );
1351
4.47k
    bufs[i] = PelBuf( cPelBuf.bufAt( 0, 0 ), cPelBuf.stride, cPelBuf.width, cPelBuf.height );
1352
4.47k
  }
1353
1.49k
}
1354
1355
void PelStorage::compactResize( const UnitArea& area )
1356
1.97M
{
1357
1.97M
  CHECK( bufs.size() < area.blocks.size(), "Cannot increase buffer size when compacting!" );
1358
1359
7.88M
  for( uint32_t i = 0; i < area.blocks.size(); i++ )
1360
5.91M
  {
1361
5.91M
    CHECK( m_maxArea.blocks[i].area() < area.blocks[i].area(), "Cannot increase buffer size when compacting!" );
1362
1363
5.91M
    bufs[i].Size::operator=( area.blocks[i].size() );
1364
5.91M
    bufs[i].stride = bufs[i].width;
1365
5.91M
  }
1366
1.97M
}
1367
1368
void PelStorage::takeOwnership( PelStorage& other )
1369
0
{
1370
0
  chromaFormat = other.chromaFormat;
1371
1372
0
  const uint32_t numCh = getNumberValidComponents( chromaFormat );
1373
1374
0
  bufs.resize(numCh);
1375
1376
0
  for( uint32_t i = 0; i < numCh; i++ )
1377
0
  {
1378
0
    PelBuf cPelBuf = other.get( ComponentID( i ) );
1379
0
    bufs[i] = PelBuf( cPelBuf.bufAt( 0, 0 ), cPelBuf.stride, cPelBuf.width, cPelBuf.height );
1380
0
    std::swap( m_origin[i], other.m_origin[i]);
1381
0
  }
1382
1383
0
  m_maxArea = other.m_maxArea;
1384
1385
0
  other.destroy();
1386
0
}
1387
1388
1389
void PelStorage::swap( PelStorage& other )
1390
0
{
1391
0
  const uint32_t numCh = getNumberValidComponents( chromaFormat );
1392
1393
0
  for( uint32_t i = 0; i < numCh; i++ )
1394
0
  {
1395
    // check this otherwise it would turn out to get very weird
1396
0
    CHECK( chromaFormat                   != other.chromaFormat                  , "Incompatible formats" );
1397
0
    CHECK( get( ComponentID( i ) )        != other.get( ComponentID( i ) )       , "Incompatible formats" );
1398
0
    CHECK( get( ComponentID( i ) ).stride != other.get( ComponentID( i ) ).stride, "Incompatible formats" );
1399
1400
0
    std::swap( bufs[i].buf,    other.bufs[i].buf );
1401
0
    std::swap( bufs[i].stride, other.bufs[i].stride );
1402
0
    std::swap( m_origin[i],    other.m_origin[i] );
1403
0
  }
1404
0
}
1405
1406
void PelStorage::destroy()
1407
2.02M
{
1408
2.02M
  chromaFormat = NUM_CHROMA_FORMAT;
1409
8.10M
  for( uint32_t i = 0; i < MAX_NUM_COMP; i++ )
1410
6.07M
  {
1411
6.07M
    if( m_origin[i] )
1412
1.06M
    {
1413
1.06M
      xFree( m_origin[i] );
1414
1.06M
      m_origin[i] = nullptr;
1415
1.06M
    }
1416
6.07M
  }
1417
2.02M
  bufs.clear();
1418
2.02M
}
1419
1420
PelBuf PelStorage::getBuf( const ComponentID CompID )
1421
20.3k
{
1422
20.3k
  return bufs[CompID];
1423
20.3k
}
1424
1425
const CPelBuf PelStorage::getBuf( const ComponentID CompID ) const
1426
0
{
1427
0
  return bufs[CompID];
1428
0
}
1429
1430
PelBuf PelStorage::getBuf( const CompArea& blk )
1431
26.6M
{
1432
26.6M
  const PelBuf& r = bufs[blk.compID];
1433
26.6M
  return PelBuf( r.buf + rsAddr( blk, r.stride ), r.stride, blk );
1434
26.6M
}
1435
1436
const CPelBuf PelStorage::getBuf( const CompArea& blk ) const
1437
37.2k
{
1438
37.2k
  const PelBuf& r = bufs[blk.compID];
1439
37.2k
  return CPelBuf( r.buf + rsAddr( blk, r.stride ), r.stride, blk );
1440
37.2k
}
1441
1442
PelUnitBuf PelStorage::getBuf( const UnitArea& unit )
1443
4.97k
{
1444
4.97k
  return ( chromaFormat == CHROMA_400 ) ? PelUnitBuf( chromaFormat, getBuf( unit.Y() ) ) : PelUnitBuf( chromaFormat, getBuf( unit.Y() ), getBuf( unit.Cb() ), getBuf( unit.Cr() ) );
1445
4.97k
}
1446
1447
const CPelUnitBuf PelStorage::getBuf( const UnitArea& unit ) const
1448
0
{
1449
0
  return ( chromaFormat == CHROMA_400 ) ? CPelUnitBuf( chromaFormat, getBuf( unit.Y() ) ) : CPelUnitBuf( chromaFormat, getBuf( unit.Y() ), getBuf( unit.Cb() ), getBuf( unit.Cr() ) );
1450
0
}
1451
1452
PelUnitBuf PelStorage::getBuf(const int strY, const int strCb, const int strCr, const UnitArea& unit)
1453
0
{
1454
0
  CHECKD( unit.Y().width > bufs[COMP_Y].width && unit.Y().height > bufs[COMP_Y].height, "unsuported request" );
1455
0
  CHECKD( strY > bufs[COMP_Y].stride, "unsuported request" );
1456
0
  CHECKD( strCb > bufs[COMP_Cb].stride, "unsuported request" );
1457
0
  CHECKD( strCr > bufs[COMP_Cr].stride, "unsuported request" );
1458
0
  return (chromaFormat == CHROMA_400) ? PelUnitBuf(chromaFormat, PelBuf( bufs[COMP_Y].buf, strY, unit.Y())) : PelUnitBuf(chromaFormat, PelBuf( bufs[COMP_Y].buf, strY, unit.Y()), PelBuf( bufs[COMP_Cb].buf, strCb, unit.Cb()), PelBuf( bufs[COMP_Cr].buf, strCr, unit.Cr()));
1459
0
}
1460
1461
const CPelUnitBuf PelStorage::getBuf(const int strY, const int strCb, const int strCr, const UnitArea& unit) const
1462
0
{
1463
0
  CHECKD( unit.Y().width > bufs[COMP_Y].width && unit.Y().height > bufs[COMP_Y].height, "unsuported request" );
1464
0
  CHECKD( strY > bufs[COMP_Y].stride, "unsuported request" );
1465
0
  CHECKD( strCb > bufs[COMP_Cb].stride, "unsuported request" );
1466
0
  CHECKD( strCr > bufs[COMP_Cr].stride, "unsuported request" );
1467
0
  return (chromaFormat == CHROMA_400) ? CPelUnitBuf(chromaFormat, CPelBuf( bufs[COMP_Y].buf, strY, unit.Y())) : CPelUnitBuf(chromaFormat, CPelBuf( bufs[COMP_Y].buf, strY, unit.Y()), CPelBuf( bufs[COMP_Cb].buf, strCb, unit.Cb()), CPelBuf( bufs[COMP_Cr].buf, strCr, unit.Cr()));
1468
0
}
1469
1470
PelUnitBuf PelStorage::getBufPart(const UnitArea& unit)
1471
0
{
1472
0
  CHECKD( unit.Y().width > bufs[COMP_Y].width && unit.Y().height > bufs[COMP_Y].height, "unsuported request" );
1473
0
  return (chromaFormat == CHROMA_400) ? PelUnitBuf(chromaFormat, PelBuf( bufs[COMP_Y].buf, bufs[COMP_Y].stride, unit.Y())) : PelUnitBuf(chromaFormat, PelBuf( bufs[COMP_Y].buf, bufs[COMP_Y].stride, unit.Y()), PelBuf( bufs[COMP_Cb].buf, bufs[COMP_Cb].stride, unit.Cb()), PelBuf( bufs[COMP_Cr].buf, bufs[COMP_Cr].stride, unit.Cr()));
1474
0
}
1475
1476
const CPelUnitBuf PelStorage::getBufPart(const UnitArea& unit) const
1477
0
{
1478
0
  CHECKD(unit.Y().width > bufs[COMP_Y].width && unit.Y().height > bufs[COMP_Y].height, "unsuported request");
1479
0
  return (chromaFormat == CHROMA_400) ? CPelUnitBuf(chromaFormat, CPelBuf(bufs[COMP_Y].buf, unit.Y().width, unit.Y())) : CPelUnitBuf(chromaFormat, CPelBuf(bufs[COMP_Y].buf, unit.Y().width, unit.Y()), CPelBuf(bufs[COMP_Cb].buf, unit.Cb().width, unit.Cb()), CPelBuf(bufs[COMP_Cr].buf, unit.Cr().width, unit.Cr()));
1480
0
}
1481
1482
const CPelUnitBuf PelStorage::getCompactBuf(const UnitArea& unit) const
1483
0
{
1484
0
  CHECKD( unit.Y().width > bufs[COMP_Y].width && unit.Y().height > bufs[COMP_Y].height, "unsuported request" );
1485
1486
0
  PelUnitBuf ret;
1487
0
  ret.chromaFormat = chromaFormat;
1488
0
  ret.bufs.resize_noinit( chromaFormat == CHROMA_400 ? 1 : 3 );
1489
  
1490
0
  ret.Y   ().buf = bufs[COMP_Y ].buf; ret.Y ().width = ret.Y ().stride = unit.Y ().width; ret.Y ().height = unit.Y ().height;
1491
0
  if( chromaFormat != CHROMA_400 )
1492
0
  {
1493
0
    ret.Cb().buf = bufs[COMP_Cb].buf; ret.Cb().width = ret.Cb().stride = unit.Cb().width; ret.Cb().height = unit.Cb().height;
1494
0
    ret.Cr().buf = bufs[COMP_Cr].buf; ret.Cr().width = ret.Cr().stride = unit.Cr().width; ret.Cr().height = unit.Cr().height;
1495
0
  }
1496
1497
0
  return ret;
1498
0
}
1499
1500
PelUnitBuf PelStorage::getCompactBuf(const UnitArea& unit)
1501
183k
{
1502
183k
  CHECKD( unit.Y().width > bufs[COMP_Y].width && unit.Y().height > bufs[COMP_Y].height, "unsuported request" );
1503
1504
183k
  PelUnitBuf ret;
1505
183k
  ret.chromaFormat = chromaFormat;
1506
183k
  ret.bufs.resize_noinit( chromaFormat == CHROMA_400 ? 1 : 3 );
1507
1508
183k
  ret.Y   ().buf = bufs[COMP_Y ].buf; ret.Y ().width = ret.Y ().stride = unit.Y ().width; ret.Y ().height = unit.Y ().height;
1509
183k
  if( chromaFormat != CHROMA_400 )
1510
183k
  {
1511
183k
    ret.Cb().buf = bufs[COMP_Cb].buf; ret.Cb().width = ret.Cb().stride = unit.Cb().width; ret.Cb().height = unit.Cb().height;
1512
183k
    ret.Cr().buf = bufs[COMP_Cr].buf; ret.Cr().width = ret.Cr().stride = unit.Cr().width; ret.Cr().height = unit.Cr().height;
1513
183k
  }
1514
1515
183k
  return ret;
1516
183k
}
1517
1518
const CPelBuf PelStorage::getCompactBuf(const CompArea& carea) const
1519
0
{
1520
0
  return CPelBuf( bufs[carea.compID].buf, carea.width, carea);
1521
0
}
1522
1523
PelBuf PelStorage::getCompactBuf(const CompArea& carea)
1524
0
{
1525
0
  return PelBuf( bufs[carea.compID].buf, carea.width, carea);
1526
0
}
1527
1528
void downsampleYuv(PelBuf& dest, const vvencYUVPlane& yuvPlaneIn, int downsampleStep)
1529
0
{
1530
0
  const int widthd = dest.width;
1531
0
  const int heightd = dest.height;
1532
0
  int difStride = dest.stride - dest.width;
1533
1534
0
  const int16_t* src = yuvPlaneIn.ptr;
1535
0
  const int instride = yuvPlaneIn.stride;
1536
0
  int n = 0;
1537
0
  for (int j = 0; j < heightd; j++)
1538
0
  {
1539
0
    int i = 0;
1540
0
    for (i = 0; i < widthd; i++)
1541
0
    {
1542
0
      long int b = 0;
1543
0
      for (int r = 0; r < downsampleStep; r++)
1544
0
      {
1545
0
        int posr = instride * r;
1546
0
        for (int n = 0; n < downsampleStep; n++)
1547
0
        {
1548
0
          b += src[posr + n];
1549
0
        }
1550
0
      }
1551
0
      src += downsampleStep;
1552
0
      dest.buf[n] = (int16_t)((b + 2) / (downsampleStep << 1));
1553
0
      n++;
1554
0
    }
1555
0
    n += difStride;
1556
0
    src = src - downsampleStep * i + instride * downsampleStep;
1557
0
  }
1558
0
}
1559
1560
void copyPadToPelUnitBuf( PelUnitBuf pelUnitBuf, const vvencYUVBuffer& yuvBuffer, const ChromaFormat& chFmt )
1561
1.49k
{
1562
1.49k
  CHECK( pelUnitBuf.bufs.size() == 0, "pelUnitBuf not initialized" );
1563
1.49k
  pelUnitBuf.chromaFormat = chFmt;
1564
1.49k
  const int numComp = getNumberValidComponents( chFmt );
1565
5.97k
  for ( int i = 0; i < numComp; i++ )
1566
4.47k
  {
1567
4.47k
    const vvencYUVPlane& src = yuvBuffer.planes[ i ];
1568
4.47k
    CHECK( src.ptr == nullptr, "yuvBuffer not setup" );
1569
4.47k
    PelBuf& dest = pelUnitBuf.bufs[i];
1570
4.47k
    CHECK( dest.buf == nullptr, "yuvBuffer not setup" );
1571
1572
4.47k
    if (dest.width < src.width)
1573
0
    {
1574
0
      downsampleYuv(dest, src, 2);
1575
0
    }
1576
4.47k
    else
1577
4.47k
    {
1578
480k
      for (int y = 0; y < src.height; y++)
1579
476k
      {
1580
476k
        ::memcpy(dest.buf + y * dest.stride, src.ptr + y * src.stride, src.width * sizeof(int16_t));
1581
1582
        // pad right if required
1583
476k
        for (int x = src.width; x < dest.width; x++)
1584
0
        {
1585
0
          dest.buf[x + y * dest.stride] = dest.buf[src.width - 1 + y * dest.stride];
1586
0
        }
1587
476k
      }
1588
1589
      // pad bottom if required
1590
4.47k
      for (int y = src.height; y < dest.height; y++)
1591
0
      {
1592
0
        ::memcpy(dest.buf + y * dest.stride, dest.buf + (src.height - 1) * dest.stride, dest.width * sizeof(int16_t));
1593
0
      }
1594
4.47k
    }
1595
4.47k
  }
1596
1.49k
}
1597
1598
/*
1599
void setupPelUnitBuf( const YUVBuffer& yuvBuffer, PelUnitBuf& pelUnitBuf, const ChromaFormat& chFmt )
1600
{
1601
  CHECK( pelUnitBuf.bufs.size() != 0, "pelUnitBuf already in use" );
1602
  pelUnitBuf.chromaFormat = chFmt;
1603
  const int numComp = getNumberValidComponents( chFmt );
1604
  for ( int i = 0; i < numComp; i++ )
1605
  {
1606
    const YUVBuffer::Plane& yuvPlane = yuvBuffer.planes[ i ];
1607
    CHECK( yuvPlane.ptr == nullptr, "yuvBuffer not setup" );
1608
    PelBuf area( yuvPlane.ptr, yuvPlane.stride, yuvPlane.width, yuvPlane.height );
1609
    pelUnitBuf.bufs.push_back( area );
1610
  }
1611
}
1612
*/
1613
void setupYuvBuffer ( const PelUnitBuf& pelUnitBuf, vvencYUVBuffer& yuvBuffer, const Window* confWindow )
1614
0
{
1615
0
  const ChromaFormat chFmt = pelUnitBuf.chromaFormat;
1616
0
  const int numComp        = getNumberValidComponents( chFmt );
1617
0
  for ( int i = 0; i < numComp; i++ )
1618
0
  {
1619
0
    const ComponentID compId = ComponentID( i );
1620
0
          PelBuf area        = pelUnitBuf.get( compId );
1621
0
    const int sx             = getComponentScaleX( compId, chFmt );
1622
0
    const int sy             = getComponentScaleY( compId, chFmt );
1623
0
    vvencYUVPlane& yuvPlane = yuvBuffer.planes[ i ];
1624
0
    CHECK( yuvPlane.ptr != nullptr, "yuvBuffer already in use" );
1625
0
    yuvPlane.ptr             = area.bufAt( confWindow->winLeftOffset >> sx, confWindow->winTopOffset >> sy );
1626
0
    yuvPlane.width           = ( ( area.width  << sx ) - ( confWindow->winLeftOffset + confWindow->winRightOffset  ) ) >> sx;
1627
0
    yuvPlane.height          = ( ( area.height << sy ) - ( confWindow->winTopOffset  + confWindow->winBottomOffset ) ) >> sy;
1628
0
    yuvPlane.stride          = area.stride;
1629
0
  }
1630
0
}
1631
1632
} // namespace vvenc
1633
1634
//! \}
1635