/src/x265/source/common/intrapred.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * Copyright (C) 2013-2020 MulticoreWare, Inc |
3 | | * |
4 | | * Authors: Min Chen <chenm003@163.com> |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 2 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. |
19 | | * |
20 | | * This program is also available under a commercial proprietary license. |
21 | | * For more information, contact us at license @ x265.com. |
22 | | *****************************************************************************/ |
23 | | |
24 | | #include "common.h" |
25 | | #include "primitives.h" |
26 | | |
27 | | using namespace X265_NS; |
28 | | |
29 | | namespace { |
30 | | |
31 | | template<int tuSize> |
32 | | void intraFilter(const pixel* samples, pixel* filtered) /* 1:2:1 filtering of left and top reference samples */ |
33 | 1.43M | { |
34 | 1.43M | const int tuSize2 = tuSize << 1; |
35 | | |
36 | 1.43M | pixel topLeft = samples[0], topLast = samples[tuSize2], leftLast = samples[tuSize2 + tuSize2]; |
37 | | |
38 | | // filtering top |
39 | 26.8M | for (int i = 1; i < tuSize2; i++) |
40 | 25.4M | filtered[i] = ((samples[i] << 1) + samples[i - 1] + samples[i + 1] + 2) >> 2; |
41 | 1.43M | filtered[tuSize2] = topLast; |
42 | | |
43 | | // filtering top-left |
44 | 1.43M | filtered[0] = ((topLeft << 1) + samples[1] + samples[tuSize2 + 1] + 2) >> 2; |
45 | | |
46 | | // filtering left |
47 | 1.43M | filtered[tuSize2 + 1] = ((samples[tuSize2 + 1] << 1) + topLeft + samples[tuSize2 + 2] + 2) >> 2; |
48 | 25.4M | for (int i = tuSize2 + 2; i < tuSize2 + tuSize2; i++) |
49 | 24.0M | filtered[i] = ((samples[i] << 1) + samples[i - 1] + samples[i + 1] + 2) >> 2; |
50 | 1.43M | filtered[tuSize2 + tuSize2] = leftLast; |
51 | 1.43M | } Unexecuted instantiation: intrapred.cpp:void (anonymous namespace)::intraFilter<4>(unsigned char const*, unsigned char*) intrapred.cpp:void (anonymous namespace)::intraFilter<8>(unsigned char const*, unsigned char*) Line | Count | Source | 33 | 1.19M | { | 34 | 1.19M | const int tuSize2 = tuSize << 1; | 35 | | | 36 | 1.19M | pixel topLeft = samples[0], topLast = samples[tuSize2], leftLast = samples[tuSize2 + tuSize2]; | 37 | | | 38 | | // filtering top | 39 | 19.1M | for (int i = 1; i < tuSize2; i++) | 40 | 17.9M | filtered[i] = ((samples[i] << 1) + samples[i - 1] + samples[i + 1] + 2) >> 2; | 41 | 1.19M | filtered[tuSize2] = topLast; | 42 | | | 43 | | // filtering top-left | 44 | 1.19M | filtered[0] = ((topLeft << 1) + samples[1] + samples[tuSize2 + 1] + 2) >> 2; | 45 | | | 46 | | // filtering left | 47 | 1.19M | filtered[tuSize2 + 1] = ((samples[tuSize2 + 1] << 1) + topLeft + samples[tuSize2 + 2] + 2) >> 2; | 48 | 17.9M | for (int i = tuSize2 + 2; i < tuSize2 + tuSize2; i++) | 49 | 16.7M | filtered[i] = ((samples[i] << 1) + samples[i - 1] + samples[i + 1] + 2) >> 2; | 50 | 1.19M | filtered[tuSize2 + tuSize2] = leftLast; | 51 | 1.19M | } |
intrapred.cpp:void (anonymous namespace)::intraFilter<16>(unsigned char const*, unsigned char*) Line | Count | Source | 33 | 242k | { | 34 | 242k | const int tuSize2 = tuSize << 1; | 35 | | | 36 | 242k | pixel topLeft = samples[0], topLast = samples[tuSize2], leftLast = samples[tuSize2 + tuSize2]; | 37 | | | 38 | | // filtering top | 39 | 7.75M | for (int i = 1; i < tuSize2; i++) | 40 | 7.51M | filtered[i] = ((samples[i] << 1) + samples[i - 1] + samples[i + 1] + 2) >> 2; | 41 | 242k | filtered[tuSize2] = topLast; | 42 | | | 43 | | // filtering top-left | 44 | 242k | filtered[0] = ((topLeft << 1) + samples[1] + samples[tuSize2 + 1] + 2) >> 2; | 45 | | | 46 | | // filtering left | 47 | 242k | filtered[tuSize2 + 1] = ((samples[tuSize2 + 1] << 1) + topLeft + samples[tuSize2 + 2] + 2) >> 2; | 48 | 7.51M | for (int i = tuSize2 + 2; i < tuSize2 + tuSize2; i++) | 49 | 7.27M | filtered[i] = ((samples[i] << 1) + samples[i - 1] + samples[i + 1] + 2) >> 2; | 50 | 242k | filtered[tuSize2 + tuSize2] = leftLast; | 51 | 242k | } |
Unexecuted instantiation: intrapred.cpp:void (anonymous namespace)::intraFilter<32>(unsigned char const*, unsigned char*) |
52 | | |
53 | | static void dcPredFilter(const pixel* above, const pixel* left, pixel* dst, intptr_t dststride, int size) |
54 | 2.81M | { |
55 | | // boundary pixels processing |
56 | 2.81M | dst[0] = (pixel)((above[0] + left[0] + 2 * dst[0] + 2) >> 2); |
57 | | |
58 | 15.6M | for (int x = 1; x < size; x++) |
59 | 12.8M | dst[x] = (pixel)((above[x] + 3 * dst[x] + 2) >> 2); |
60 | | |
61 | 2.81M | dst += dststride; |
62 | 15.6M | for (int y = 1; y < size; y++) |
63 | 12.8M | { |
64 | 12.8M | *dst = (pixel)((left[y] + 3 * *dst + 2) >> 2); |
65 | 12.8M | dst += dststride; |
66 | 12.8M | } |
67 | 2.81M | } |
68 | | |
69 | | template<int width> |
70 | | void intra_pred_dc_c(pixel* dst, intptr_t dstStride, const pixel* srcPix, int /*dirMode*/, int bFilter) |
71 | 4.39M | { |
72 | 4.39M | int k, l; |
73 | | |
74 | 4.39M | int dcVal = width; |
75 | 28.4M | for (int i = 0; i < width; i++) |
76 | 24.0M | dcVal += srcPix[1 + i] + srcPix[2 * width + 1 + i]; |
77 | | |
78 | 4.39M | dcVal = dcVal / (width + width); |
79 | 28.4M | for (k = 0; k < width; k++) |
80 | 212M | for (l = 0; l < width; l++) |
81 | 188M | dst[k * dstStride + l] = (pixel)dcVal; |
82 | | |
83 | 4.39M | if (bFilter) |
84 | 2.82M | dcPredFilter(srcPix + 1, srcPix + (2 * width + 1), dst, dstStride, width); |
85 | 4.39M | } intrapred.cpp:void (anonymous namespace)::intra_pred_dc_c<4>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 71 | 3.37M | { | 72 | 3.37M | int k, l; | 73 | | | 74 | 3.37M | int dcVal = width; | 75 | 16.8M | for (int i = 0; i < width; i++) | 76 | 13.4M | dcVal += srcPix[1 + i] + srcPix[2 * width + 1 + i]; | 77 | | | 78 | 3.37M | dcVal = dcVal / (width + width); | 79 | 16.8M | for (k = 0; k < width; k++) | 80 | 67.4M | for (l = 0; l < width; l++) | 81 | 53.9M | dst[k * dstStride + l] = (pixel)dcVal; | 82 | | | 83 | 3.37M | if (bFilter) | 84 | 2.02M | dcPredFilter(srcPix + 1, srcPix + (2 * width + 1), dst, dstStride, width); | 85 | 3.37M | } |
intrapred.cpp:void (anonymous namespace)::intra_pred_dc_c<8>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 71 | 806k | { | 72 | 806k | int k, l; | 73 | | | 74 | 806k | int dcVal = width; | 75 | 7.25M | for (int i = 0; i < width; i++) | 76 | 6.44M | dcVal += srcPix[1 + i] + srcPix[2 * width + 1 + i]; | 77 | | | 78 | 806k | dcVal = dcVal / (width + width); | 79 | 7.25M | for (k = 0; k < width; k++) | 80 | 58.0M | for (l = 0; l < width; l++) | 81 | 51.5M | dst[k * dstStride + l] = (pixel)dcVal; | 82 | | | 83 | 806k | if (bFilter) | 84 | 642k | dcPredFilter(srcPix + 1, srcPix + (2 * width + 1), dst, dstStride, width); | 85 | 806k | } |
intrapred.cpp:void (anonymous namespace)::intra_pred_dc_c<16>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 71 | 188k | { | 72 | 188k | int k, l; | 73 | | | 74 | 188k | int dcVal = width; | 75 | 3.21M | for (int i = 0; i < width; i++) | 76 | 3.02M | dcVal += srcPix[1 + i] + srcPix[2 * width + 1 + i]; | 77 | | | 78 | 188k | dcVal = dcVal / (width + width); | 79 | 3.20M | for (k = 0; k < width; k++) | 80 | 51.3M | for (l = 0; l < width; l++) | 81 | 48.3M | dst[k * dstStride + l] = (pixel)dcVal; | 82 | | | 83 | 188k | if (bFilter) | 84 | 154k | dcPredFilter(srcPix + 1, srcPix + (2 * width + 1), dst, dstStride, width); | 85 | 188k | } |
intrapred.cpp:void (anonymous namespace)::intra_pred_dc_c<32>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 71 | 33.5k | { | 72 | 33.5k | int k, l; | 73 | | | 74 | 33.5k | int dcVal = width; | 75 | 1.10M | for (int i = 0; i < width; i++) | 76 | 1.07M | dcVal += srcPix[1 + i] + srcPix[2 * width + 1 + i]; | 77 | | | 78 | 33.5k | dcVal = dcVal / (width + width); | 79 | 1.10M | for (k = 0; k < width; k++) | 80 | 35.4M | for (l = 0; l < width; l++) | 81 | 34.3M | dst[k * dstStride + l] = (pixel)dcVal; | 82 | | | 83 | 33.5k | if (bFilter) | 84 | 0 | dcPredFilter(srcPix + 1, srcPix + (2 * width + 1), dst, dstStride, width); | 85 | 33.5k | } |
|
86 | | |
87 | | template<int log2Size> |
88 | | void planar_pred_c(pixel* dst, intptr_t dstStride, const pixel* srcPix, int /*dirMode*/, int /*bFilter*/) |
89 | 7.67M | { |
90 | 7.67M | const int blkSize = 1 << log2Size; |
91 | | |
92 | 7.67M | const pixel* above = srcPix + 1; |
93 | 7.67M | const pixel* left = srcPix + (2 * blkSize + 1); |
94 | | |
95 | 7.67M | pixel topRight = above[blkSize]; |
96 | 7.67M | pixel bottomLeft = left[blkSize]; |
97 | 48.1M | for (int y = 0; y < blkSize; y++) |
98 | 330M | for (int x = 0; x < blkSize; x++) |
99 | 290M | dst[y * dstStride + x] = (pixel) (((blkSize - 1 - x) * left[y] + (blkSize - 1 -y) * above[x] + (x + 1) * topRight + (y + 1) * bottomLeft + blkSize) >> (log2Size + 1)); |
100 | 7.67M | } intrapred.cpp:void (anonymous namespace)::planar_pred_c<2>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 89 | 6.00M | { | 90 | 6.00M | const int blkSize = 1 << log2Size; | 91 | | | 92 | 6.00M | const pixel* above = srcPix + 1; | 93 | 6.00M | const pixel* left = srcPix + (2 * blkSize + 1); | 94 | | | 95 | 6.00M | pixel topRight = above[blkSize]; | 96 | 6.00M | pixel bottomLeft = left[blkSize]; | 97 | 30.0M | for (int y = 0; y < blkSize; y++) | 98 | 120M | for (int x = 0; x < blkSize; x++) | 99 | 96.0M | dst[y * dstStride + x] = (pixel) (((blkSize - 1 - x) * left[y] + (blkSize - 1 -y) * above[x] + (x + 1) * topRight + (y + 1) * bottomLeft + blkSize) >> (log2Size + 1)); | 100 | 6.00M | } |
intrapred.cpp:void (anonymous namespace)::planar_pred_c<3>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 89 | 1.35M | { | 90 | 1.35M | const int blkSize = 1 << log2Size; | 91 | | | 92 | 1.35M | const pixel* above = srcPix + 1; | 93 | 1.35M | const pixel* left = srcPix + (2 * blkSize + 1); | 94 | | | 95 | 1.35M | pixel topRight = above[blkSize]; | 96 | 1.35M | pixel bottomLeft = left[blkSize]; | 97 | 12.2M | for (int y = 0; y < blkSize; y++) | 98 | 97.7M | for (int x = 0; x < blkSize; x++) | 99 | 86.9M | dst[y * dstStride + x] = (pixel) (((blkSize - 1 - x) * left[y] + (blkSize - 1 -y) * above[x] + (x + 1) * topRight + (y + 1) * bottomLeft + blkSize) >> (log2Size + 1)); | 100 | 1.35M | } |
intrapred.cpp:void (anonymous namespace)::planar_pred_c<4>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 89 | 274k | { | 90 | 274k | const int blkSize = 1 << log2Size; | 91 | | | 92 | 274k | const pixel* above = srcPix + 1; | 93 | 274k | const pixel* left = srcPix + (2 * blkSize + 1); | 94 | | | 95 | 274k | pixel topRight = above[blkSize]; | 96 | 274k | pixel bottomLeft = left[blkSize]; | 97 | 4.65M | for (int y = 0; y < blkSize; y++) | 98 | 74.4M | for (int x = 0; x < blkSize; x++) | 99 | 70.0M | dst[y * dstStride + x] = (pixel) (((blkSize - 1 - x) * left[y] + (blkSize - 1 -y) * above[x] + (x + 1) * topRight + (y + 1) * bottomLeft + blkSize) >> (log2Size + 1)); | 100 | 274k | } |
intrapred.cpp:void (anonymous namespace)::planar_pred_c<5>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 89 | 36.3k | { | 90 | 36.3k | const int blkSize = 1 << log2Size; | 91 | | | 92 | 36.3k | const pixel* above = srcPix + 1; | 93 | 36.3k | const pixel* left = srcPix + (2 * blkSize + 1); | 94 | | | 95 | 36.3k | pixel topRight = above[blkSize]; | 96 | 36.3k | pixel bottomLeft = left[blkSize]; | 97 | 1.19M | for (int y = 0; y < blkSize; y++) | 98 | 38.3M | for (int x = 0; x < blkSize; x++) | 99 | 37.1M | dst[y * dstStride + x] = (pixel) (((blkSize - 1 - x) * left[y] + (blkSize - 1 -y) * above[x] + (x + 1) * topRight + (y + 1) * bottomLeft + blkSize) >> (log2Size + 1)); | 100 | 36.3k | } |
|
101 | | |
102 | | template<int width> |
103 | | void intra_pred_ang_c(pixel* dst, intptr_t dstStride, const pixel *srcPix0, int dirMode, int bFilter) |
104 | 64.0M | { |
105 | 64.0M | int width2 = width << 1; |
106 | | // Flip the neighbours in the horizontal case. |
107 | 64.0M | int horMode = dirMode < 18; |
108 | 64.0M | pixel neighbourBuf[129]; |
109 | 64.0M | const pixel *srcPix = srcPix0; |
110 | | |
111 | 64.0M | if (horMode) |
112 | 30.7M | { |
113 | 30.7M | neighbourBuf[0] = srcPix[0]; |
114 | 373M | for (int i = 0; i < width << 1; i++) |
115 | 343M | { |
116 | 343M | neighbourBuf[1 + i] = srcPix[width2 + 1 + i]; |
117 | 343M | neighbourBuf[width2 + 1 + i] = srcPix[1 + i]; |
118 | 343M | } |
119 | 30.7M | srcPix = neighbourBuf; |
120 | 30.7M | } |
121 | | |
122 | | // Intra prediction angle and inverse angle tables. |
123 | 64.0M | const int8_t angleTable[17] = { -32, -26, -21, -17, -13, -9, -5, -2, 0, 2, 5, 9, 13, 17, 21, 26, 32 }; |
124 | 64.0M | const int16_t invAngleTable[8] = { 4096, 1638, 910, 630, 482, 390, 315, 256 }; |
125 | | |
126 | | // Get the prediction angle. |
127 | 64.0M | int angleOffset = horMode ? 10 - dirMode : dirMode - 26; |
128 | 64.0M | int angle = angleTable[8 + angleOffset]; |
129 | | |
130 | | // Vertical Prediction. |
131 | 64.0M | if (!angle) |
132 | 6.85M | { |
133 | 42.5M | for (int y = 0; y < width; y++) |
134 | 290M | for (int x = 0; x < width; x++) |
135 | 255M | dst[y * dstStride + x] = srcPix[1 + x]; |
136 | | |
137 | 6.85M | if (bFilter) |
138 | 3.72M | { |
139 | 3.72M | int topLeft = srcPix[0], top = srcPix[1]; |
140 | 23.7M | for (int y = 0; y < width; y++) |
141 | 20.0M | dst[y * dstStride] = x265_clip((int16_t)(top + ((srcPix[width2 + 1 + y] - topLeft) >> 1))); |
142 | 3.72M | } |
143 | 6.85M | } |
144 | 57.2M | else // Angular prediction. |
145 | 57.2M | { |
146 | | // Get the reference pixels. The reference base is the first pixel to the top (neighbourBuf[1]). |
147 | 57.2M | pixel refBuf[64]; |
148 | 57.2M | const pixel *ref; |
149 | | |
150 | | // Use the projected left neighbours and the top neighbours. |
151 | 57.2M | if (angle < 0) |
152 | 27.0M | { |
153 | | // Number of neighbours projected. |
154 | 27.0M | int nbProjected = -((width * angle) >> 5) - 1; |
155 | 27.0M | pixel *ref_pix = refBuf + nbProjected + 1; |
156 | | |
157 | | // Project the neighbours. |
158 | 27.0M | int invAngle = invAngleTable[- angleOffset - 1]; |
159 | 27.0M | int invAngleSum = 128; |
160 | 84.3M | for (int i = 0; i < nbProjected; i++) |
161 | 57.2M | { |
162 | 57.2M | invAngleSum += invAngle; |
163 | 57.2M | ref_pix[- 2 - i] = srcPix[width2 + (invAngleSum >> 8)]; |
164 | 57.2M | } |
165 | | |
166 | | // Copy the top-left and top pixels. |
167 | 205M | for (int i = 0; i < width + 1; i++) |
168 | 178M | ref_pix[-1 + i] = srcPix[i]; |
169 | 27.0M | ref = ref_pix; |
170 | 27.0M | } |
171 | 30.1M | else // Use the top and top-right neighbours. |
172 | 30.1M | ref = srcPix + 1; |
173 | | |
174 | | // Pass every row. |
175 | 57.2M | int angleSum = 0; |
176 | 376M | for (int y = 0; y < width; y++) |
177 | 319M | { |
178 | 319M | angleSum += angle; |
179 | 319M | int offset = angleSum >> 5; |
180 | 319M | int fraction = angleSum & 31; |
181 | | |
182 | 319M | if (fraction) // Interpolate |
183 | 2.57G | for (int x = 0; x < width; x++) |
184 | 2.28G | dst[y * dstStride + x] = (pixel)(((32 - fraction) * ref[offset + x] + fraction * ref[offset + x + 1] + 16) >> 5); |
185 | 37.2M | else // Copy. |
186 | 353M | for (int x = 0; x < width; x++) |
187 | 316M | dst[y * dstStride + x] = ref[offset + x]; |
188 | 319M | } |
189 | 57.2M | } |
190 | | |
191 | | // Flip for horizontal. |
192 | 64.0M | if (horMode) |
193 | 30.7M | { |
194 | 171M | for (int y = 0; y < width - 1; y++) |
195 | 140M | { |
196 | 749M | for (int x = y + 1; x < width; x++) |
197 | 608M | { |
198 | 608M | pixel tmp = dst[y * dstStride + x]; |
199 | 608M | dst[y * dstStride + x] = dst[x * dstStride + y]; |
200 | 608M | dst[x * dstStride + y] = tmp; |
201 | 608M | } |
202 | 140M | } |
203 | 30.7M | } |
204 | 64.0M | } intrapred.cpp:void (anonymous namespace)::intra_pred_ang_c<4>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 104 | 48.1M | { | 105 | 48.1M | int width2 = width << 1; | 106 | | // Flip the neighbours in the horizontal case. | 107 | 48.1M | int horMode = dirMode < 18; | 108 | 48.1M | pixel neighbourBuf[129]; | 109 | 48.1M | const pixel *srcPix = srcPix0; | 110 | | | 111 | 48.1M | if (horMode) | 112 | 22.9M | { | 113 | 22.9M | neighbourBuf[0] = srcPix[0]; | 114 | 206M | for (int i = 0; i < width << 1; i++) | 115 | 183M | { | 116 | 183M | neighbourBuf[1 + i] = srcPix[width2 + 1 + i]; | 117 | 183M | neighbourBuf[width2 + 1 + i] = srcPix[1 + i]; | 118 | 183M | } | 119 | 22.9M | srcPix = neighbourBuf; | 120 | 22.9M | } | 121 | | | 122 | | // Intra prediction angle and inverse angle tables. | 123 | 48.1M | const int8_t angleTable[17] = { -32, -26, -21, -17, -13, -9, -5, -2, 0, 2, 5, 9, 13, 17, 21, 26, 32 }; | 124 | 48.1M | const int16_t invAngleTable[8] = { 4096, 1638, 910, 630, 482, 390, 315, 256 }; | 125 | | | 126 | | // Get the prediction angle. | 127 | 48.1M | int angleOffset = horMode ? 10 - dirMode : dirMode - 26; | 128 | 48.1M | int angle = angleTable[8 + angleOffset]; | 129 | | | 130 | | // Vertical Prediction. | 131 | 48.1M | if (!angle) | 132 | 5.47M | { | 133 | 27.3M | for (int y = 0; y < width; y++) | 134 | 109M | for (int x = 0; x < width; x++) | 135 | 87.5M | dst[y * dstStride + x] = srcPix[1 + x]; | 136 | | | 137 | 5.47M | if (bFilter) | 138 | 2.77M | { | 139 | 2.77M | int topLeft = srcPix[0], top = srcPix[1]; | 140 | 13.8M | for (int y = 0; y < width; y++) | 141 | 11.1M | dst[y * dstStride] = x265_clip((int16_t)(top + ((srcPix[width2 + 1 + y] - topLeft) >> 1))); | 142 | 2.77M | } | 143 | 5.47M | } | 144 | 42.7M | else // Angular prediction. | 145 | 42.7M | { | 146 | | // Get the reference pixels. The reference base is the first pixel to the top (neighbourBuf[1]). | 147 | 42.7M | pixel refBuf[64]; | 148 | 42.7M | const pixel *ref; | 149 | | | 150 | | // Use the projected left neighbours and the top neighbours. | 151 | 42.7M | if (angle < 0) | 152 | 20.2M | { | 153 | | // Number of neighbours projected. | 154 | 20.2M | int nbProjected = -((width * angle) >> 5) - 1; | 155 | 20.2M | pixel *ref_pix = refBuf + nbProjected + 1; | 156 | | | 157 | | // Project the neighbours. | 158 | 20.2M | int invAngle = invAngleTable[- angleOffset - 1]; | 159 | 20.2M | int invAngleSum = 128; | 160 | 48.5M | for (int i = 0; i < nbProjected; i++) | 161 | 28.3M | { | 162 | 28.3M | invAngleSum += invAngle; | 163 | 28.3M | ref_pix[- 2 - i] = srcPix[width2 + (invAngleSum >> 8)]; | 164 | 28.3M | } | 165 | | | 166 | | // Copy the top-left and top pixels. | 167 | 121M | for (int i = 0; i < width + 1; i++) | 168 | 101M | ref_pix[-1 + i] = srcPix[i]; | 169 | 20.2M | ref = ref_pix; | 170 | 20.2M | } | 171 | 22.4M | else // Use the top and top-right neighbours. | 172 | 22.4M | ref = srcPix + 1; | 173 | | | 174 | | // Pass every row. | 175 | 42.7M | int angleSum = 0; | 176 | 213M | for (int y = 0; y < width; y++) | 177 | 170M | { | 178 | 170M | angleSum += angle; | 179 | 170M | int offset = angleSum >> 5; | 180 | 170M | int fraction = angleSum & 31; | 181 | | | 182 | 170M | if (fraction) // Interpolate | 183 | 748M | for (int x = 0; x < width; x++) | 184 | 599M | dst[y * dstStride + x] = (pixel)(((32 - fraction) * ref[offset + x] + fraction * ref[offset + x + 1] + 16) >> 5); | 185 | 20.7M | else // Copy. | 186 | 107M | for (int x = 0; x < width; x++) | 187 | 86.3M | dst[y * dstStride + x] = ref[offset + x]; | 188 | 170M | } | 189 | 42.7M | } | 190 | | | 191 | | // Flip for horizontal. | 192 | 48.1M | if (horMode) | 193 | 22.9M | { | 194 | 91.6M | for (int y = 0; y < width - 1; y++) | 195 | 68.7M | { | 196 | 206M | for (int x = y + 1; x < width; x++) | 197 | 137M | { | 198 | 137M | pixel tmp = dst[y * dstStride + x]; | 199 | 137M | dst[y * dstStride + x] = dst[x * dstStride + y]; | 200 | 137M | dst[x * dstStride + y] = tmp; | 201 | 137M | } | 202 | 68.7M | } | 203 | 22.9M | } | 204 | 48.1M | } |
intrapred.cpp:void (anonymous namespace)::intra_pred_ang_c<8>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 104 | 12.5M | { | 105 | 12.5M | int width2 = width << 1; | 106 | | // Flip the neighbours in the horizontal case. | 107 | 12.5M | int horMode = dirMode < 18; | 108 | 12.5M | pixel neighbourBuf[129]; | 109 | 12.5M | const pixel *srcPix = srcPix0; | 110 | | | 111 | 12.5M | if (horMode) | 112 | 6.18M | { | 113 | 6.18M | neighbourBuf[0] = srcPix[0]; | 114 | 105M | for (int i = 0; i < width << 1; i++) | 115 | 98.9M | { | 116 | 98.9M | neighbourBuf[1 + i] = srcPix[width2 + 1 + i]; | 117 | 98.9M | neighbourBuf[width2 + 1 + i] = srcPix[1 + i]; | 118 | 98.9M | } | 119 | 6.18M | srcPix = neighbourBuf; | 120 | 6.18M | } | 121 | | | 122 | | // Intra prediction angle and inverse angle tables. | 123 | 12.5M | const int8_t angleTable[17] = { -32, -26, -21, -17, -13, -9, -5, -2, 0, 2, 5, 9, 13, 17, 21, 26, 32 }; | 124 | 12.5M | const int16_t invAngleTable[8] = { 4096, 1638, 910, 630, 482, 390, 315, 256 }; | 125 | | | 126 | | // Get the prediction angle. | 127 | 12.5M | int angleOffset = horMode ? 10 - dirMode : dirMode - 26; | 128 | 12.5M | int angle = angleTable[8 + angleOffset]; | 129 | | | 130 | | // Vertical Prediction. | 131 | 12.5M | if (!angle) | 132 | 1.11M | { | 133 | 10.0M | for (int y = 0; y < width; y++) | 134 | 80.0M | for (int x = 0; x < width; x++) | 135 | 71.1M | dst[y * dstStride + x] = srcPix[1 + x]; | 136 | | | 137 | 1.11M | if (bFilter) | 138 | 784k | { | 139 | 784k | int topLeft = srcPix[0], top = srcPix[1]; | 140 | 7.05M | for (int y = 0; y < width; y++) | 141 | 6.27M | dst[y * dstStride] = x265_clip((int16_t)(top + ((srcPix[width2 + 1 + y] - topLeft) >> 1))); | 142 | 784k | } | 143 | 1.11M | } | 144 | 11.4M | else // Angular prediction. | 145 | 11.4M | { | 146 | | // Get the reference pixels. The reference base is the first pixel to the top (neighbourBuf[1]). | 147 | 11.4M | pixel refBuf[64]; | 148 | 11.4M | const pixel *ref; | 149 | | | 150 | | // Use the projected left neighbours and the top neighbours. | 151 | 11.4M | if (angle < 0) | 152 | 5.33M | { | 153 | | // Number of neighbours projected. | 154 | 5.33M | int nbProjected = -((width * angle) >> 5) - 1; | 155 | 5.33M | pixel *ref_pix = refBuf + nbProjected + 1; | 156 | | | 157 | | // Project the neighbours. | 158 | 5.33M | int invAngle = invAngleTable[- angleOffset - 1]; | 159 | 5.33M | int invAngleSum = 128; | 160 | 22.6M | for (int i = 0; i < nbProjected; i++) | 161 | 17.3M | { | 162 | 17.3M | invAngleSum += invAngle; | 163 | 17.3M | ref_pix[- 2 - i] = srcPix[width2 + (invAngleSum >> 8)]; | 164 | 17.3M | } | 165 | | | 166 | | // Copy the top-left and top pixels. | 167 | 53.3M | for (int i = 0; i < width + 1; i++) | 168 | 47.9M | ref_pix[-1 + i] = srcPix[i]; | 169 | 5.33M | ref = ref_pix; | 170 | 5.33M | } | 171 | 6.07M | else // Use the top and top-right neighbours. | 172 | 6.07M | ref = srcPix + 1; | 173 | | | 174 | | // Pass every row. | 175 | 11.4M | int angleSum = 0; | 176 | 102M | for (int y = 0; y < width; y++) | 177 | 90.8M | { | 178 | 90.8M | angleSum += angle; | 179 | 90.8M | int offset = angleSum >> 5; | 180 | 90.8M | int fraction = angleSum & 31; | 181 | | | 182 | 90.8M | if (fraction) // Interpolate | 183 | 733M | for (int x = 0; x < width; x++) | 184 | 652M | dst[y * dstStride + x] = (pixel)(((32 - fraction) * ref[offset + x] + fraction * ref[offset + x + 1] + 16) >> 5); | 185 | 9.24M | else // Copy. | 186 | 84.6M | for (int x = 0; x < width; x++) | 187 | 75.3M | dst[y * dstStride + x] = ref[offset + x]; | 188 | 90.8M | } | 189 | 11.4M | } | 190 | | | 191 | | // Flip for horizontal. | 192 | 12.5M | if (horMode) | 193 | 6.18M | { | 194 | 49.4M | for (int y = 0; y < width - 1; y++) | 195 | 43.2M | { | 196 | 216M | for (int x = y + 1; x < width; x++) | 197 | 173M | { | 198 | 173M | pixel tmp = dst[y * dstStride + x]; | 199 | 173M | dst[y * dstStride + x] = dst[x * dstStride + y]; | 200 | 173M | dst[x * dstStride + y] = tmp; | 201 | 173M | } | 202 | 43.2M | } | 203 | 6.18M | } | 204 | 12.5M | } |
intrapred.cpp:void (anonymous namespace)::intra_pred_ang_c<16>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 104 | 2.79M | { | 105 | 2.79M | int width2 = width << 1; | 106 | | // Flip the neighbours in the horizontal case. | 107 | 2.79M | int horMode = dirMode < 18; | 108 | 2.79M | pixel neighbourBuf[129]; | 109 | 2.79M | const pixel *srcPix = srcPix0; | 110 | | | 111 | 2.79M | if (horMode) | 112 | 1.34M | { | 113 | 1.34M | neighbourBuf[0] = srcPix[0]; | 114 | 44.2M | for (int i = 0; i < width << 1; i++) | 115 | 42.9M | { | 116 | 42.9M | neighbourBuf[1 + i] = srcPix[width2 + 1 + i]; | 117 | 42.9M | neighbourBuf[width2 + 1 + i] = srcPix[1 + i]; | 118 | 42.9M | } | 119 | 1.34M | srcPix = neighbourBuf; | 120 | 1.34M | } | 121 | | | 122 | | // Intra prediction angle and inverse angle tables. | 123 | 2.79M | const int8_t angleTable[17] = { -32, -26, -21, -17, -13, -9, -5, -2, 0, 2, 5, 9, 13, 17, 21, 26, 32 }; | 124 | 2.79M | const int16_t invAngleTable[8] = { 4096, 1638, 910, 630, 482, 390, 315, 256 }; | 125 | | | 126 | | // Get the prediction angle. | 127 | 2.79M | int angleOffset = horMode ? 10 - dirMode : dirMode - 26; | 128 | 2.79M | int angle = angleTable[8 + angleOffset]; | 129 | | | 130 | | // Vertical Prediction. | 131 | 2.79M | if (!angle) | 132 | 236k | { | 133 | 4.01M | for (int y = 0; y < width; y++) | 134 | 64.1M | for (int x = 0; x < width; x++) | 135 | 60.4M | dst[y * dstStride + x] = srcPix[1 + x]; | 136 | | | 137 | 236k | if (bFilter) | 138 | 167k | { | 139 | 167k | int topLeft = srcPix[0], top = srcPix[1]; | 140 | 2.84M | for (int y = 0; y < width; y++) | 141 | 2.68M | dst[y * dstStride] = x265_clip((int16_t)(top + ((srcPix[width2 + 1 + y] - topLeft) >> 1))); | 142 | 167k | } | 143 | 236k | } | 144 | 2.56M | else // Angular prediction. | 145 | 2.56M | { | 146 | | // Get the reference pixels. The reference base is the first pixel to the top (neighbourBuf[1]). | 147 | 2.56M | pixel refBuf[64]; | 148 | 2.56M | const pixel *ref; | 149 | | | 150 | | // Use the projected left neighbours and the top neighbours. | 151 | 2.56M | if (angle < 0) | 152 | 1.22M | { | 153 | | // Number of neighbours projected. | 154 | 1.22M | int nbProjected = -((width * angle) >> 5) - 1; | 155 | 1.22M | pixel *ref_pix = refBuf + nbProjected + 1; | 156 | | | 157 | | // Project the neighbours. | 158 | 1.22M | int invAngle = invAngleTable[- angleOffset - 1]; | 159 | 1.22M | int invAngleSum = 128; | 160 | 9.30M | for (int i = 0; i < nbProjected; i++) | 161 | 8.07M | { | 162 | 8.07M | invAngleSum += invAngle; | 163 | 8.07M | ref_pix[- 2 - i] = srcPix[width2 + (invAngleSum >> 8)]; | 164 | 8.07M | } | 165 | | | 166 | | // Copy the top-left and top pixels. | 167 | 22.0M | for (int i = 0; i < width + 1; i++) | 168 | 20.7M | ref_pix[-1 + i] = srcPix[i]; | 169 | 1.22M | ref = ref_pix; | 170 | 1.22M | } | 171 | 1.33M | else // Use the top and top-right neighbours. | 172 | 1.33M | ref = srcPix + 1; | 173 | | | 174 | | // Pass every row. | 175 | 2.56M | int angleSum = 0; | 176 | 43.2M | for (int y = 0; y < width; y++) | 177 | 40.7M | { | 178 | 40.7M | angleSum += angle; | 179 | 40.7M | int offset = angleSum >> 5; | 180 | 40.7M | int fraction = angleSum & 31; | 181 | | | 182 | 40.7M | if (fraction) // Interpolate | 183 | 605M | for (int x = 0; x < width; x++) | 184 | 569M | dst[y * dstStride + x] = (pixel)(((32 - fraction) * ref[offset + x] + fraction * ref[offset + x + 1] + 16) >> 5); | 185 | 5.03M | else // Copy. | 186 | 86.8M | for (int x = 0; x < width; x++) | 187 | 81.8M | dst[y * dstStride + x] = ref[offset + x]; | 188 | 40.7M | } | 189 | 2.56M | } | 190 | | | 191 | | // Flip for horizontal. | 192 | 2.79M | if (horMode) | 193 | 1.34M | { | 194 | 21.4M | for (int y = 0; y < width - 1; y++) | 195 | 20.1M | { | 196 | 181M | for (int x = y + 1; x < width; x++) | 197 | 160M | { | 198 | 160M | pixel tmp = dst[y * dstStride + x]; | 199 | 160M | dst[y * dstStride + x] = dst[x * dstStride + y]; | 200 | 160M | dst[x * dstStride + y] = tmp; | 201 | 160M | } | 202 | 20.1M | } | 203 | 1.34M | } | 204 | 2.79M | } |
intrapred.cpp:void (anonymous namespace)::intra_pred_ang_c<32>(unsigned char*, long, unsigned char const*, int, int) Line | Count | Source | 104 | 574k | { | 105 | 574k | int width2 = width << 1; | 106 | | // Flip the neighbours in the horizontal case. | 107 | 574k | int horMode = dirMode < 18; | 108 | 574k | pixel neighbourBuf[129]; | 109 | 574k | const pixel *srcPix = srcPix0; | 110 | | | 111 | 574k | if (horMode) | 112 | 279k | { | 113 | 279k | neighbourBuf[0] = srcPix[0]; | 114 | 18.1M | for (int i = 0; i < width << 1; i++) | 115 | 17.8M | { | 116 | 17.8M | neighbourBuf[1 + i] = srcPix[width2 + 1 + i]; | 117 | 17.8M | neighbourBuf[width2 + 1 + i] = srcPix[1 + i]; | 118 | 17.8M | } | 119 | 279k | srcPix = neighbourBuf; | 120 | 279k | } | 121 | | | 122 | | // Intra prediction angle and inverse angle tables. | 123 | 574k | const int8_t angleTable[17] = { -32, -26, -21, -17, -13, -9, -5, -2, 0, 2, 5, 9, 13, 17, 21, 26, 32 }; | 124 | 574k | const int16_t invAngleTable[8] = { 4096, 1638, 910, 630, 482, 390, 315, 256 }; | 125 | | | 126 | | // Get the prediction angle. | 127 | 574k | int angleOffset = horMode ? 10 - dirMode : dirMode - 26; | 128 | 574k | int angle = angleTable[8 + angleOffset]; | 129 | | | 130 | | // Vertical Prediction. | 131 | 574k | if (!angle) | 132 | 35.1k | { | 133 | 1.15M | for (int y = 0; y < width; y++) | 134 | 37.0M | for (int x = 0; x < width; x++) | 135 | 35.9M | dst[y * dstStride + x] = srcPix[1 + x]; | 136 | | | 137 | 35.1k | if (bFilter) | 138 | 0 | { | 139 | 0 | int topLeft = srcPix[0], top = srcPix[1]; | 140 | 0 | for (int y = 0; y < width; y++) | 141 | 0 | dst[y * dstStride] = x265_clip((int16_t)(top + ((srcPix[width2 + 1 + y] - topLeft) >> 1))); | 142 | 0 | } | 143 | 35.1k | } | 144 | 539k | else // Angular prediction. | 145 | 539k | { | 146 | | // Get the reference pixels. The reference base is the first pixel to the top (neighbourBuf[1]). | 147 | 539k | pixel refBuf[64]; | 148 | 539k | const pixel *ref; | 149 | | | 150 | | // Use the projected left neighbours and the top neighbours. | 151 | 539k | if (angle < 0) | 152 | 260k | { | 153 | | // Number of neighbours projected. | 154 | 260k | int nbProjected = -((width * angle) >> 5) - 1; | 155 | 260k | pixel *ref_pix = refBuf + nbProjected + 1; | 156 | | | 157 | | // Project the neighbours. | 158 | 260k | int invAngle = invAngleTable[- angleOffset - 1]; | 159 | 260k | int invAngleSum = 128; | 160 | 3.78M | for (int i = 0; i < nbProjected; i++) | 161 | 3.52M | { | 162 | 3.52M | invAngleSum += invAngle; | 163 | 3.52M | ref_pix[- 2 - i] = srcPix[width2 + (invAngleSum >> 8)]; | 164 | 3.52M | } | 165 | | | 166 | | // Copy the top-left and top pixels. | 167 | 8.84M | for (int i = 0; i < width + 1; i++) | 168 | 8.58M | ref_pix[-1 + i] = srcPix[i]; | 169 | 260k | ref = ref_pix; | 170 | 260k | } | 171 | 279k | else // Use the top and top-right neighbours. | 172 | 279k | ref = srcPix + 1; | 173 | | | 174 | | // Pass every row. | 175 | 539k | int angleSum = 0; | 176 | 17.4M | for (int y = 0; y < width; y++) | 177 | 16.8M | { | 178 | 16.8M | angleSum += angle; | 179 | 16.8M | int offset = angleSum >> 5; | 180 | 16.8M | int fraction = angleSum & 31; | 181 | | | 182 | 16.8M | if (fraction) // Interpolate | 183 | 482M | for (int x = 0; x < width; x++) | 184 | 467M | dst[y * dstStride + x] = (pixel)(((32 - fraction) * ref[offset + x] + fraction * ref[offset + x + 1] + 16) >> 5); | 185 | 2.19M | else // Copy. | 186 | 75.3M | for (int x = 0; x < width; x++) | 187 | 73.1M | dst[y * dstStride + x] = ref[offset + x]; | 188 | 16.8M | } | 189 | 539k | } | 190 | | | 191 | | // Flip for horizontal. | 192 | 574k | if (horMode) | 193 | 279k | { | 194 | 8.86M | for (int y = 0; y < width - 1; y++) | 195 | 8.58M | { | 196 | 145M | for (int x = y + 1; x < width; x++) | 197 | 137M | { | 198 | 137M | pixel tmp = dst[y * dstStride + x]; | 199 | 137M | dst[y * dstStride + x] = dst[x * dstStride + y]; | 200 | 137M | dst[x * dstStride + y] = tmp; | 201 | 137M | } | 202 | 8.58M | } | 203 | 279k | } | 204 | 574k | } |
|
205 | | |
206 | | template<int log2Size> |
207 | | void all_angs_pred_c(pixel *dest, pixel *refPix, pixel *filtPix, int bLuma) |
208 | 0 | { |
209 | 0 | const int size = 1 << log2Size; |
210 | 0 | for (int mode = 2; mode <= 34; mode++) |
211 | 0 | { |
212 | 0 | pixel *srcPix = (g_intraFilterFlags[mode] & size ? filtPix : refPix); |
213 | 0 | pixel *out = dest + ((mode - 2) << (log2Size * 2)); |
214 | |
|
215 | 0 | intra_pred_ang_c<size>(out, size, srcPix, mode, bLuma); |
216 | | |
217 | | // Optimize code don't flip buffer |
218 | 0 | bool modeHor = (mode < 18); |
219 | | |
220 | | // transpose the block if this is a horizontal mode |
221 | 0 | if (modeHor) |
222 | 0 | { |
223 | 0 | for (int k = 0; k < size - 1; k++) |
224 | 0 | { |
225 | 0 | for (int l = k + 1; l < size; l++) |
226 | 0 | { |
227 | 0 | pixel tmp = out[k * size + l]; |
228 | 0 | out[k * size + l] = out[l * size + k]; |
229 | 0 | out[l * size + k] = tmp; |
230 | 0 | } |
231 | 0 | } |
232 | 0 | } |
233 | 0 | } |
234 | 0 | } Unexecuted instantiation: intrapred.cpp:void (anonymous namespace)::all_angs_pred_c<2>(unsigned char*, unsigned char*, unsigned char*, int) Unexecuted instantiation: intrapred.cpp:void (anonymous namespace)::all_angs_pred_c<3>(unsigned char*, unsigned char*, unsigned char*, int) Unexecuted instantiation: intrapred.cpp:void (anonymous namespace)::all_angs_pred_c<4>(unsigned char*, unsigned char*, unsigned char*, int) Unexecuted instantiation: intrapred.cpp:void (anonymous namespace)::all_angs_pred_c<5>(unsigned char*, unsigned char*, unsigned char*, int) |
235 | | } |
236 | | |
237 | | namespace X265_NS { |
238 | | // x265 private namespace |
239 | | |
240 | | void setupIntraPrimitives_c(EncoderPrimitives& p) |
241 | 1 | { |
242 | 1 | p.cu[BLOCK_4x4].intra_filter = intraFilter<4>; |
243 | 1 | p.cu[BLOCK_8x8].intra_filter = intraFilter<8>; |
244 | 1 | p.cu[BLOCK_16x16].intra_filter = intraFilter<16>; |
245 | 1 | p.cu[BLOCK_32x32].intra_filter = intraFilter<32>; |
246 | | |
247 | 1 | p.cu[BLOCK_4x4].intra_pred[PLANAR_IDX] = planar_pred_c<2>; |
248 | 1 | p.cu[BLOCK_8x8].intra_pred[PLANAR_IDX] = planar_pred_c<3>; |
249 | 1 | p.cu[BLOCK_16x16].intra_pred[PLANAR_IDX] = planar_pred_c<4>; |
250 | 1 | p.cu[BLOCK_32x32].intra_pred[PLANAR_IDX] = planar_pred_c<5>; |
251 | | |
252 | 1 | p.cu[BLOCK_4x4].intra_pred[DC_IDX] = intra_pred_dc_c<4>; |
253 | 1 | p.cu[BLOCK_8x8].intra_pred[DC_IDX] = intra_pred_dc_c<8>; |
254 | 1 | p.cu[BLOCK_16x16].intra_pred[DC_IDX] = intra_pred_dc_c<16>; |
255 | 1 | p.cu[BLOCK_32x32].intra_pred[DC_IDX] = intra_pred_dc_c<32>; |
256 | | |
257 | 34 | for (int i = 2; i < NUM_INTRA_MODE; i++) |
258 | 33 | { |
259 | 33 | p.cu[BLOCK_4x4].intra_pred[i] = intra_pred_ang_c<4>; |
260 | 33 | p.cu[BLOCK_8x8].intra_pred[i] = intra_pred_ang_c<8>; |
261 | 33 | p.cu[BLOCK_16x16].intra_pred[i] = intra_pred_ang_c<16>; |
262 | 33 | p.cu[BLOCK_32x32].intra_pred[i] = intra_pred_ang_c<32>; |
263 | 33 | } |
264 | | |
265 | 1 | p.cu[BLOCK_4x4].intra_pred_allangs = all_angs_pred_c<2>; |
266 | 1 | p.cu[BLOCK_8x8].intra_pred_allangs = all_angs_pred_c<3>; |
267 | 1 | p.cu[BLOCK_16x16].intra_pred_allangs = all_angs_pred_c<4>; |
268 | 1 | p.cu[BLOCK_32x32].intra_pred_allangs = all_angs_pred_c<5>; |
269 | 1 | } |
270 | | } |