/src/libde265/libde265/intrapred.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * H.265 video codec. |
3 | | * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de> |
4 | | * |
5 | | * This file is part of libde265. |
6 | | * |
7 | | * libde265 is free software: you can redistribute it and/or modify |
8 | | * it under the terms of the GNU Lesser General Public License as |
9 | | * published by the Free Software Foundation, either version 3 of |
10 | | * the License, or (at your option) any later version. |
11 | | * |
12 | | * libde265 is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public License |
18 | | * along with libde265. If not, see <http://www.gnu.org/licenses/>. |
19 | | */ |
20 | | |
21 | | #ifndef DE265_INTRAPRED_H |
22 | | #define DE265_INTRAPRED_H |
23 | | |
24 | | #include "libde265/decctx.h" |
25 | | |
26 | | extern const int intraPredAngle_table[1+34]; |
27 | | |
28 | | |
29 | | /* Fill the three intra-pred-mode candidates into candModeList. |
30 | | Block position is (x,y) and you also have to give the PUidx for this |
31 | | block (which is (x>>Log2MinPUSize) + (y>>Log2MinPUSize)*PicWidthInMinPUs). |
32 | | availableA/B is the output of check_CTB_available(). |
33 | | */ |
34 | | void fillIntraPredModeCandidates(enum IntraPredMode candModeList[3], |
35 | | int x,int y, int PUidx, |
36 | | bool availableA, // left |
37 | | bool availableB, // top |
38 | | const de265_image* img); |
39 | | |
40 | | |
41 | | inline void fillIntraPredModeCandidates(enum IntraPredMode candModeList[3], int x,int y, |
42 | | bool availableA, // left |
43 | | bool availableB, // top |
44 | | const de265_image* img) |
45 | 0 | { |
46 | 0 | int PUidx = img->get_sps().getPUIndexRS(x,y); |
47 | 0 | fillIntraPredModeCandidates(candModeList, x,y, PUidx, availableA,availableB, img); |
48 | 0 | } |
49 | | |
50 | | void fillIntraPredModeCandidates(enum IntraPredMode candModeList[3], |
51 | | enum IntraPredMode candIntraPredModeA, |
52 | | enum IntraPredMode candIntraPredModeB); |
53 | | |
54 | | |
55 | | /* Return value >= 0 -> use mpm_idx(return value) |
56 | | else -> use rem_intra(-return value-1) |
57 | | |
58 | | This function may modify the candModeList ! |
59 | | */ |
60 | | int find_intra_pred_mode(enum IntraPredMode mode, |
61 | | enum IntraPredMode candModeList[3]); |
62 | | |
63 | | void list_chroma_pred_candidates(enum IntraPredMode chroma_mode[5], |
64 | | enum IntraPredMode luma_mode); |
65 | | |
66 | | int get_intra_scan_idx(int log2TrafoSize, enum IntraPredMode intraPredMode, int cIdx, |
67 | | const seq_parameter_set* sps); |
68 | | |
69 | | int get_intra_scan_idx_luma (int log2TrafoSize, enum IntraPredMode intraPredMode); // DEPRECATED |
70 | | int get_intra_scan_idx_chroma(int log2TrafoSize, enum IntraPredMode intraPredMode); // DEPRECATED |
71 | | |
72 | | enum IntraPredMode lumaPredMode_to_chromaPredMode(enum IntraPredMode luma, |
73 | | enum IntraChromaPredMode chroma); |
74 | | |
75 | | /* |
76 | | void decode_intra_block(decoder_context* ctx, |
77 | | thread_context* tctx, |
78 | | int cIdx, |
79 | | int xB0,int yB0, // position of TU in frame (chroma adapted) |
80 | | int x0,int y0, // position of CU in frame (chroma adapted) |
81 | | int log2TrafoSize, int trafoDepth, |
82 | | enum IntraPredMode intraPredMode, |
83 | | bool transform_skip_flag); |
84 | | */ |
85 | | |
86 | | //void fill_border_samples(decoder_context* ctx, int xB,int yB, |
87 | | // int nT, int cIdx, uint8_t* out_border); |
88 | | |
89 | | void decode_intra_prediction(de265_image* img, |
90 | | int xB0,int yB0, |
91 | | enum IntraPredMode intraPredMode, |
92 | | int nT, int cIdx); |
93 | | |
94 | | // TODO: remove this |
95 | | template <class pixel_t> void decode_intra_prediction(de265_image* img, |
96 | | int xB0,int yB0, |
97 | | enum IntraPredMode intraPredMode, |
98 | | pixel_t* dst, int nT, int cIdx); |
99 | | |
100 | | |
101 | | |
102 | | |
103 | | // --- internal use only --- |
104 | | |
105 | | // Actually, the largest TB block can only be 32, but in some intra-pred-mode algorithms |
106 | | // (e.g. min-residual), we may call intra prediction on the maximum CTB size (64). |
107 | | static const int MAX_INTRA_PRED_BLOCK_SIZE = 64; |
108 | | |
109 | | |
110 | | template <class pixel_t> |
111 | | class intra_border_computer |
112 | | { |
113 | | public: |
114 | | pixel_t* out_border; |
115 | | |
116 | | const de265_image* img; |
117 | | int nT; |
118 | | int cIdx; |
119 | | |
120 | | int xB,yB; |
121 | | |
122 | | const seq_parameter_set* sps; |
123 | | const pic_parameter_set* pps; |
124 | | |
125 | | uint8_t available_data[4*MAX_INTRA_PRED_BLOCK_SIZE + 1]; |
126 | | uint8_t* available; |
127 | | |
128 | | int SubWidth; |
129 | | int SubHeight; |
130 | | |
131 | | bool availableLeft; // is CTB at left side available? |
132 | | bool availableTop; // is CTB at top side available? |
133 | | bool availableTopRight; // is CTB at top-right side available? |
134 | | bool availableTopLeft; // if CTB at top-left pixel available? |
135 | | |
136 | | int nBottom; |
137 | | int nRight; |
138 | | int nAvail; |
139 | | pixel_t firstValue; |
140 | | |
141 | | void init(pixel_t* _out_border, |
142 | 5.68M | const de265_image* _img, int _nT, int _cIdx, int _xB, int _yB) { |
143 | 5.68M | img=_img; nT=_nT; cIdx=_cIdx; |
144 | 5.68M | out_border=_out_border; xB=_xB; yB=_yB; |
145 | | |
146 | 5.68M | assert(nT <= MAX_INTRA_PRED_BLOCK_SIZE); |
147 | | |
148 | 5.68M | availableLeft=true; |
149 | 5.68M | availableTop=true; |
150 | 5.68M | availableTopRight=true; |
151 | 5.68M | availableTopLeft=true; |
152 | 5.68M | } intra_border_computer<unsigned short>::init(unsigned short*, de265_image const*, int, int, int, int) Line | Count | Source | 142 | 2.07M | const de265_image* _img, int _nT, int _cIdx, int _xB, int _yB) { | 143 | 2.07M | img=_img; nT=_nT; cIdx=_cIdx; | 144 | 2.07M | out_border=_out_border; xB=_xB; yB=_yB; | 145 | | | 146 | 2.07M | assert(nT <= MAX_INTRA_PRED_BLOCK_SIZE); | 147 | | | 148 | 2.07M | availableLeft=true; | 149 | 2.07M | availableTop=true; | 150 | 2.07M | availableTopRight=true; | 151 | 2.07M | availableTopLeft=true; | 152 | 2.07M | } |
intra_border_computer<unsigned char>::init(unsigned char*, de265_image const*, int, int, int, int) Line | Count | Source | 142 | 3.61M | const de265_image* _img, int _nT, int _cIdx, int _xB, int _yB) { | 143 | 3.61M | img=_img; nT=_nT; cIdx=_cIdx; | 144 | 3.61M | out_border=_out_border; xB=_xB; yB=_yB; | 145 | | | 146 | 3.61M | assert(nT <= MAX_INTRA_PRED_BLOCK_SIZE); | 147 | | | 148 | 3.61M | availableLeft=true; | 149 | 3.61M | availableTop=true; | 150 | 3.61M | availableTopRight=true; | 151 | 3.61M | availableTopLeft=true; | 152 | 3.61M | } |
|
153 | | void preproc(); |
154 | | void fill_from_image(); |
155 | | |
156 | | void reference_sample_substitution(); |
157 | | }; |
158 | | |
159 | | |
160 | | #ifdef DE265_LOG_TRACE |
161 | | template <class pixel_t> |
162 | | void print_border(pixel_t* data, uint8_t* available, int nT) |
163 | | { |
164 | | for (int i=-2*nT ; i<=2*nT ; i++) { |
165 | | if (i==0 || i==1 || i==-nT || i==nT+1) { |
166 | | logtrace(LogIntraPred,"|"); |
167 | | } else { |
168 | | logtrace(LogIntraPred," "); |
169 | | } |
170 | | |
171 | | if (available==NULL || available[i]) { |
172 | | logtrace(LogIntraPred,"%02x",data[i]); |
173 | | } |
174 | | else { |
175 | | logtrace(LogIntraPred,"--"); |
176 | | } |
177 | | } |
178 | | } |
179 | | #else |
180 | | #define print_border(data, available, nT) |
181 | | #endif |
182 | | |
183 | | |
184 | | // (8.4.4.2.3) |
185 | | template <class pixel_t> |
186 | | void intra_prediction_sample_filtering(const seq_parameter_set& sps, |
187 | | pixel_t* p, |
188 | | int nT, int cIdx, |
189 | | enum IntraPredMode intraPredMode) |
190 | 2.21M | { |
191 | 2.21M | int filterFlag; |
192 | | |
193 | | //printf("filtering, mode: %d\n",intraPredMode); |
194 | | |
195 | 2.21M | if (intraPredMode==INTRA_DC || nT==4) { |
196 | 1.89M | filterFlag = 0; |
197 | 1.89M | } else { |
198 | | // int-cast below prevents a typing problem that leads to wrong results when abs_value is a macro |
199 | 313k | int minDistVerHor = libde265_min( abs_value((int)intraPredMode-26), |
200 | 313k | abs_value((int)intraPredMode-10) ); |
201 | | |
202 | | //printf("mindist: %d\n",minDistVerHor); |
203 | | |
204 | 313k | switch (nT) { |
205 | 287k | case 8: filterFlag = (minDistVerHor>7) ? 1 : 0; break; |
206 | 14.5k | case 16: filterFlag = (minDistVerHor>1) ? 1 : 0; break; |
207 | 11.2k | case 32: filterFlag = (minDistVerHor>0) ? 1 : 0; break; |
208 | | // there is no official 64x64 TB block, but we call this for some intra-pred mode algorithms |
209 | | // on the whole CB (2Nx2N mode for the whole CTB) |
210 | 0 | case 64: filterFlag = 0; break; |
211 | 0 | default: filterFlag = -1; assert(false); break; // should never happen |
212 | 313k | } |
213 | 313k | } |
214 | | |
215 | | |
216 | 2.21M | if (filterFlag) { |
217 | 196k | int biIntFlag = (sps.strong_intra_smoothing_enable_flag && |
218 | 196k | cIdx==0 && |
219 | 196k | nT==32 && |
220 | 196k | abs_value(p[0]+p[ 64]-2*p[ 32]) < (1<<(sps.bit_depth_luma-5)) && |
221 | 196k | abs_value(p[0]+p[-64]-2*p[-32]) < (1<<(sps.bit_depth_luma-5))) |
222 | 196k | ? 1 : 0; |
223 | | |
224 | 196k | pixel_t pF_mem[4*32+1]; |
225 | 196k | pixel_t* pF = &pF_mem[2*32]; |
226 | | |
227 | 196k | if (biIntFlag) { |
228 | 6.23k | pF[-2*nT] = p[-2*nT]; |
229 | 6.23k | pF[ 2*nT] = p[ 2*nT]; |
230 | 6.23k | pF[ 0] = p[ 0]; |
231 | | |
232 | 399k | for (int i=1;i<=63;i++) { |
233 | 392k | pF[-i] = p[0] + ((i*(p[-64]-p[0])+32)>>6); |
234 | 392k | pF[ i] = p[0] + ((i*(p[ 64]-p[0])+32)>>6); |
235 | 392k | } |
236 | 190k | } else { |
237 | 190k | pF[-2*nT] = p[-2*nT]; |
238 | 190k | pF[ 2*nT] = p[ 2*nT]; |
239 | | |
240 | 6.83M | for (int i=-(2*nT-1) ; i<=2*nT-1 ; i++) |
241 | 6.64M | { |
242 | 6.64M | pF[i] = (p[i+1] + 2*p[i] + p[i-1] + 2) >> 2; |
243 | 6.64M | } |
244 | 190k | } |
245 | | |
246 | | |
247 | | // copy back to original array |
248 | | |
249 | 196k | memcpy(p-2*nT, pF-2*nT, (4*nT+1) * sizeof(pixel_t)); |
250 | 196k | } |
251 | 2.01M | else { |
252 | | // do nothing ? |
253 | 2.01M | } |
254 | | |
255 | | |
256 | 2.21M | logtrace(LogIntraPred,"post filtering: "); |
257 | 2.21M | print_border(p,NULL,nT); |
258 | 2.21M | logtrace(LogIntraPred,"\n"); |
259 | 2.21M | } void intra_prediction_sample_filtering<unsigned short>(seq_parameter_set const&, unsigned short*, int, int, IntraPredMode) Line | Count | Source | 190 | 923k | { | 191 | 923k | int filterFlag; | 192 | | | 193 | | //printf("filtering, mode: %d\n",intraPredMode); | 194 | | | 195 | 923k | if (intraPredMode==INTRA_DC || nT==4) { | 196 | 822k | filterFlag = 0; | 197 | 822k | } else { | 198 | | // int-cast below prevents a typing problem that leads to wrong results when abs_value is a macro | 199 | 100k | int minDistVerHor = libde265_min( abs_value((int)intraPredMode-26), | 200 | 100k | abs_value((int)intraPredMode-10) ); | 201 | | | 202 | | //printf("mindist: %d\n",minDistVerHor); | 203 | | | 204 | 100k | switch (nT) { | 205 | 87.6k | case 8: filterFlag = (minDistVerHor>7) ? 1 : 0; break; | 206 | 7.38k | case 16: filterFlag = (minDistVerHor>1) ? 1 : 0; break; | 207 | 5.81k | case 32: filterFlag = (minDistVerHor>0) ? 1 : 0; break; | 208 | | // there is no official 64x64 TB block, but we call this for some intra-pred mode algorithms | 209 | | // on the whole CB (2Nx2N mode for the whole CTB) | 210 | 0 | case 64: filterFlag = 0; break; | 211 | 0 | default: filterFlag = -1; assert(false); break; // should never happen | 212 | 100k | } | 213 | 100k | } | 214 | | | 215 | | | 216 | 923k | if (filterFlag) { | 217 | 58.8k | int biIntFlag = (sps.strong_intra_smoothing_enable_flag && | 218 | 58.8k | cIdx==0 && | 219 | 58.8k | nT==32 && | 220 | 58.8k | abs_value(p[0]+p[ 64]-2*p[ 32]) < (1<<(sps.bit_depth_luma-5)) && | 221 | 58.8k | abs_value(p[0]+p[-64]-2*p[-32]) < (1<<(sps.bit_depth_luma-5))) | 222 | 58.8k | ? 1 : 0; | 223 | | | 224 | 58.8k | pixel_t pF_mem[4*32+1]; | 225 | 58.8k | pixel_t* pF = &pF_mem[2*32]; | 226 | | | 227 | 58.8k | if (biIntFlag) { | 228 | 3.47k | pF[-2*nT] = p[-2*nT]; | 229 | 3.47k | pF[ 2*nT] = p[ 2*nT]; | 230 | 3.47k | pF[ 0] = p[ 0]; | 231 | | | 232 | 222k | for (int i=1;i<=63;i++) { | 233 | 218k | pF[-i] = p[0] + ((i*(p[-64]-p[0])+32)>>6); | 234 | 218k | pF[ i] = p[0] + ((i*(p[ 64]-p[0])+32)>>6); | 235 | 218k | } | 236 | 55.3k | } else { | 237 | 55.3k | pF[-2*nT] = p[-2*nT]; | 238 | 55.3k | pF[ 2*nT] = p[ 2*nT]; | 239 | | | 240 | 2.14M | for (int i=-(2*nT-1) ; i<=2*nT-1 ; i++) | 241 | 2.09M | { | 242 | 2.09M | pF[i] = (p[i+1] + 2*p[i] + p[i-1] + 2) >> 2; | 243 | 2.09M | } | 244 | 55.3k | } | 245 | | | 246 | | | 247 | | // copy back to original array | 248 | | | 249 | 58.8k | memcpy(p-2*nT, pF-2*nT, (4*nT+1) * sizeof(pixel_t)); | 250 | 58.8k | } | 251 | 864k | else { | 252 | | // do nothing ? | 253 | 864k | } | 254 | | | 255 | | | 256 | 923k | logtrace(LogIntraPred,"post filtering: "); | 257 | 923k | print_border(p,NULL,nT); | 258 | 923k | logtrace(LogIntraPred,"\n"); | 259 | 923k | } |
void intra_prediction_sample_filtering<unsigned char>(seq_parameter_set const&, unsigned char*, int, int, IntraPredMode) Line | Count | Source | 190 | 1.28M | { | 191 | 1.28M | int filterFlag; | 192 | | | 193 | | //printf("filtering, mode: %d\n",intraPredMode); | 194 | | | 195 | 1.28M | if (intraPredMode==INTRA_DC || nT==4) { | 196 | 1.07M | filterFlag = 0; | 197 | 1.07M | } else { | 198 | | // int-cast below prevents a typing problem that leads to wrong results when abs_value is a macro | 199 | 212k | int minDistVerHor = libde265_min( abs_value((int)intraPredMode-26), | 200 | 212k | abs_value((int)intraPredMode-10) ); | 201 | | | 202 | | //printf("mindist: %d\n",minDistVerHor); | 203 | | | 204 | 212k | switch (nT) { | 205 | 199k | case 8: filterFlag = (minDistVerHor>7) ? 1 : 0; break; | 206 | 7.17k | case 16: filterFlag = (minDistVerHor>1) ? 1 : 0; break; | 207 | 5.44k | case 32: filterFlag = (minDistVerHor>0) ? 1 : 0; break; | 208 | | // there is no official 64x64 TB block, but we call this for some intra-pred mode algorithms | 209 | | // on the whole CB (2Nx2N mode for the whole CTB) | 210 | 0 | case 64: filterFlag = 0; break; | 211 | 0 | default: filterFlag = -1; assert(false); break; // should never happen | 212 | 212k | } | 213 | 212k | } | 214 | | | 215 | | | 216 | 1.28M | if (filterFlag) { | 217 | 137k | int biIntFlag = (sps.strong_intra_smoothing_enable_flag && | 218 | 137k | cIdx==0 && | 219 | 137k | nT==32 && | 220 | 137k | abs_value(p[0]+p[ 64]-2*p[ 32]) < (1<<(sps.bit_depth_luma-5)) && | 221 | 137k | abs_value(p[0]+p[-64]-2*p[-32]) < (1<<(sps.bit_depth_luma-5))) | 222 | 137k | ? 1 : 0; | 223 | | | 224 | 137k | pixel_t pF_mem[4*32+1]; | 225 | 137k | pixel_t* pF = &pF_mem[2*32]; | 226 | | | 227 | 137k | if (biIntFlag) { | 228 | 2.76k | pF[-2*nT] = p[-2*nT]; | 229 | 2.76k | pF[ 2*nT] = p[ 2*nT]; | 230 | 2.76k | pF[ 0] = p[ 0]; | 231 | | | 232 | 176k | for (int i=1;i<=63;i++) { | 233 | 174k | pF[-i] = p[0] + ((i*(p[-64]-p[0])+32)>>6); | 234 | 174k | pF[ i] = p[0] + ((i*(p[ 64]-p[0])+32)>>6); | 235 | 174k | } | 236 | 134k | } else { | 237 | 134k | pF[-2*nT] = p[-2*nT]; | 238 | 134k | pF[ 2*nT] = p[ 2*nT]; | 239 | | | 240 | 4.68M | for (int i=-(2*nT-1) ; i<=2*nT-1 ; i++) | 241 | 4.54M | { | 242 | 4.54M | pF[i] = (p[i+1] + 2*p[i] + p[i-1] + 2) >> 2; | 243 | 4.54M | } | 244 | 134k | } | 245 | | | 246 | | | 247 | | // copy back to original array | 248 | | | 249 | 137k | memcpy(p-2*nT, pF-2*nT, (4*nT+1) * sizeof(pixel_t)); | 250 | 137k | } | 251 | 1.15M | else { | 252 | | // do nothing ? | 253 | 1.15M | } | 254 | | | 255 | | | 256 | 1.28M | logtrace(LogIntraPred,"post filtering: "); | 257 | 1.28M | print_border(p,NULL,nT); | 258 | 1.28M | logtrace(LogIntraPred,"\n"); | 259 | 1.28M | } |
|
260 | | |
261 | | |
262 | | template <class pixel_t> |
263 | | void intra_prediction_planar(pixel_t* dst, int dstStride, |
264 | | int nT,int cIdx, |
265 | | pixel_t* border) |
266 | 2.56M | { |
267 | 2.56M | int Log2_nT = Log2(nT); |
268 | | |
269 | 13.8M | for (int y=0;y<nT;y++) |
270 | 68.3M | for (int x=0;x<nT;x++) |
271 | 57.0M | { |
272 | 57.0M | dst[x+y*dstStride] = ((nT-1-x)*border[-1-y] + (x+1)*border[ 1+nT] + |
273 | 57.0M | (nT-1-y)*border[ 1+x] + (y+1)*border[-1-nT] + nT) >> (Log2_nT+1); |
274 | 57.0M | } |
275 | | |
276 | | |
277 | 2.56M | logtrace(LogIntraPred,"result of planar prediction\n"); |
278 | | |
279 | 13.8M | for (int y=0;y<nT;y++) |
280 | 11.2M | { |
281 | 68.3M | for (int x=0;x<nT;x++) |
282 | 57.0M | logtrace(LogIntraPred,"%02x ", dst[x+y*dstStride]); |
283 | | |
284 | 11.2M | logtrace(LogIntraPred,"\n"); |
285 | 11.2M | } |
286 | 2.56M | } void intra_prediction_planar<unsigned short>(unsigned short*, int, int, int, unsigned short*) Line | Count | Source | 266 | 892k | { | 267 | 892k | int Log2_nT = Log2(nT); | 268 | | | 269 | 4.77M | for (int y=0;y<nT;y++) | 270 | 23.6M | for (int x=0;x<nT;x++) | 271 | 19.7M | { | 272 | 19.7M | dst[x+y*dstStride] = ((nT-1-x)*border[-1-y] + (x+1)*border[ 1+nT] + | 273 | 19.7M | (nT-1-y)*border[ 1+x] + (y+1)*border[-1-nT] + nT) >> (Log2_nT+1); | 274 | 19.7M | } | 275 | | | 276 | | | 277 | 892k | logtrace(LogIntraPred,"result of planar prediction\n"); | 278 | | | 279 | 4.77M | for (int y=0;y<nT;y++) | 280 | 3.88M | { | 281 | 23.6M | for (int x=0;x<nT;x++) | 282 | 19.7M | logtrace(LogIntraPred,"%02x ", dst[x+y*dstStride]); | 283 | | | 284 | 3.88M | logtrace(LogIntraPred,"\n"); | 285 | 3.88M | } | 286 | 892k | } |
void intra_prediction_planar<unsigned char>(unsigned char*, int, int, int, unsigned char*) Line | Count | Source | 266 | 1.67M | { | 267 | 1.67M | int Log2_nT = Log2(nT); | 268 | | | 269 | 9.02M | for (int y=0;y<nT;y++) | 270 | 44.6M | for (int x=0;x<nT;x++) | 271 | 37.3M | { | 272 | 37.3M | dst[x+y*dstStride] = ((nT-1-x)*border[-1-y] + (x+1)*border[ 1+nT] + | 273 | 37.3M | (nT-1-y)*border[ 1+x] + (y+1)*border[-1-nT] + nT) >> (Log2_nT+1); | 274 | 37.3M | } | 275 | | | 276 | | | 277 | 1.67M | logtrace(LogIntraPred,"result of planar prediction\n"); | 278 | | | 279 | 9.02M | for (int y=0;y<nT;y++) | 280 | 7.35M | { | 281 | 44.6M | for (int x=0;x<nT;x++) | 282 | 37.3M | logtrace(LogIntraPred,"%02x ", dst[x+y*dstStride]); | 283 | | | 284 | 7.35M | logtrace(LogIntraPred,"\n"); | 285 | 7.35M | } | 286 | 1.67M | } |
|
287 | | |
288 | | |
289 | | template <class pixel_t> |
290 | | void intra_prediction_DC(pixel_t* dst, int dstStride, |
291 | | int nT,int cIdx, |
292 | | pixel_t* border) |
293 | 531k | { |
294 | 531k | int Log2_nT = Log2(nT); |
295 | | |
296 | 531k | int dcVal = 0; |
297 | 2.87M | for (int i=0;i<nT;i++) |
298 | 2.34M | { |
299 | 2.34M | dcVal += border[ i+1]; |
300 | 2.34M | dcVal += border[-i-1]; |
301 | 2.34M | } |
302 | | |
303 | 531k | dcVal += nT; |
304 | 531k | dcVal >>= Log2_nT+1; |
305 | | |
306 | 531k | if (cIdx==0 && nT<32) { |
307 | 278k | dst[0] = (border[-1] + 2*dcVal + border[1] +2) >> 2; |
308 | | |
309 | 1.25M | for (int x=1;x<nT;x++) { dst[x] = (border[ x+1] + 3*dcVal+2)>>2; } |
310 | 1.25M | for (int y=1;y<nT;y++) { dst[y*dstStride] = (border[-y-1] + 3*dcVal+2)>>2; } |
311 | 1.25M | for (int y=1;y<nT;y++) |
312 | 5.11M | for (int x=1;x<nT;x++) |
313 | 4.13M | { |
314 | 4.13M | dst[x+y*dstStride] = dcVal; |
315 | 4.13M | } |
316 | 278k | } else { |
317 | 1.34M | for (int y=0;y<nT;y++) |
318 | 6.70M | for (int x=0;x<nT;x++) |
319 | 5.61M | { |
320 | 5.61M | dst[x+y*dstStride] = dcVal; |
321 | 5.61M | } |
322 | 253k | } |
323 | 531k | } void intra_prediction_DC<unsigned short>(unsigned short*, int, int, int, unsigned short*) Line | Count | Source | 293 | 189k | { | 294 | 189k | int Log2_nT = Log2(nT); | 295 | | | 296 | 189k | int dcVal = 0; | 297 | 1.01M | for (int i=0;i<nT;i++) | 298 | 821k | { | 299 | 821k | dcVal += border[ i+1]; | 300 | 821k | dcVal += border[-i-1]; | 301 | 821k | } | 302 | | | 303 | 189k | dcVal += nT; | 304 | 189k | dcVal >>= Log2_nT+1; | 305 | | | 306 | 189k | if (cIdx==0 && nT<32) { | 307 | 95.4k | dst[0] = (border[-1] + 2*dcVal + border[1] +2) >> 2; | 308 | | | 309 | 423k | for (int x=1;x<nT;x++) { dst[x] = (border[ x+1] + 3*dcVal+2)>>2; } | 310 | 423k | for (int y=1;y<nT;y++) { dst[y*dstStride] = (border[-y-1] + 3*dcVal+2)>>2; } | 311 | 423k | for (int y=1;y<nT;y++) | 312 | 1.65M | for (int x=1;x<nT;x++) | 313 | 1.32M | { | 314 | 1.32M | dst[x+y*dstStride] = dcVal; | 315 | 1.32M | } | 316 | 95.4k | } else { | 317 | 491k | for (int y=0;y<nT;y++) | 318 | 2.41M | for (int x=0;x<nT;x++) | 319 | 2.02M | { | 320 | 2.02M | dst[x+y*dstStride] = dcVal; | 321 | 2.02M | } | 322 | 94.0k | } | 323 | 189k | } |
void intra_prediction_DC<unsigned char>(unsigned char*, int, int, int, unsigned char*) Line | Count | Source | 293 | 342k | { | 294 | 342k | int Log2_nT = Log2(nT); | 295 | | | 296 | 342k | int dcVal = 0; | 297 | 1.86M | for (int i=0;i<nT;i++) | 298 | 1.52M | { | 299 | 1.52M | dcVal += border[ i+1]; | 300 | 1.52M | dcVal += border[-i-1]; | 301 | 1.52M | } | 302 | | | 303 | 342k | dcVal += nT; | 304 | 342k | dcVal >>= Log2_nT+1; | 305 | | | 306 | 342k | if (cIdx==0 && nT<32) { | 307 | 182k | dst[0] = (border[-1] + 2*dcVal + border[1] +2) >> 2; | 308 | | | 309 | 834k | for (int x=1;x<nT;x++) { dst[x] = (border[ x+1] + 3*dcVal+2)>>2; } | 310 | 834k | for (int y=1;y<nT;y++) { dst[y*dstStride] = (border[-y-1] + 3*dcVal+2)>>2; } | 311 | 834k | for (int y=1;y<nT;y++) | 312 | 3.46M | for (int x=1;x<nT;x++) | 313 | 2.81M | { | 314 | 2.81M | dst[x+y*dstStride] = dcVal; | 315 | 2.81M | } | 316 | 182k | } else { | 317 | 850k | for (int y=0;y<nT;y++) | 318 | 4.28M | for (int x=0;x<nT;x++) | 319 | 3.59M | { | 320 | 3.59M | dst[x+y*dstStride] = dcVal; | 321 | 3.59M | } | 322 | 159k | } | 323 | 342k | } |
|
324 | | |
325 | | |
326 | | extern const int intraPredAngle_table[1+34]; |
327 | | extern const int invAngle_table[25-10]; |
328 | | |
329 | | |
330 | | // (8.4.4.2.6) |
331 | | template <class pixel_t> |
332 | | void intra_prediction_angular(pixel_t* dst, int dstStride, |
333 | | int bit_depth, bool disableIntraBoundaryFilter, |
334 | | int xB0,int yB0, |
335 | | enum IntraPredMode intraPredMode, |
336 | | int nT,int cIdx, |
337 | | pixel_t* border) |
338 | 2.59M | { |
339 | 2.59M | pixel_t ref_mem[4*MAX_INTRA_PRED_BLOCK_SIZE+1]; // TODO: what is the required range here ? |
340 | 2.59M | pixel_t* ref=&ref_mem[2*MAX_INTRA_PRED_BLOCK_SIZE]; |
341 | | |
342 | 2.59M | assert(intraPredMode<35); |
343 | 2.59M | assert(intraPredMode>=2); |
344 | | |
345 | 2.59M | int intraPredAngle = intraPredAngle_table[intraPredMode]; |
346 | | |
347 | 2.59M | if (intraPredMode >= 18) { |
348 | | |
349 | 4.16M | for (int x=0;x<=nT;x++) |
350 | 3.55M | { ref[x] = border[x]; } |
351 | | |
352 | 609k | if (intraPredAngle<0) { |
353 | 234k | int invAngle = invAngle_table[intraPredMode-11]; |
354 | | |
355 | 234k | if ((nT*intraPredAngle)>>5 < -1) { |
356 | 685k | for (int x=(nT*intraPredAngle)>>5; x<=-1; x++) { |
357 | 528k | ref[x] = border[0-((x*invAngle+128)>>8)]; |
358 | 528k | } |
359 | 156k | } |
360 | 374k | } else { |
361 | 2.19M | for (int x=nT+1; x<=2*nT;x++) { |
362 | 1.81M | ref[x] = border[x]; |
363 | 1.81M | } |
364 | 374k | } |
365 | | |
366 | 3.55M | for (int y=0;y<nT;y++) |
367 | 21.6M | for (int x=0;x<nT;x++) |
368 | 18.6M | { |
369 | 18.6M | int iIdx = ((y+1)*intraPredAngle)>>5; |
370 | 18.6M | int iFact= ((y+1)*intraPredAngle)&31; |
371 | | |
372 | 18.6M | if (iFact != 0) { |
373 | 11.6M | dst[x+y*dstStride] = ((32-iFact)*ref[x+iIdx+1] + iFact*ref[x+iIdx+2] + 16)>>5; |
374 | 11.6M | } else { |
375 | 7.00M | dst[x+y*dstStride] = ref[x+iIdx+1]; |
376 | 7.00M | } |
377 | 18.6M | } |
378 | | |
379 | 609k | if (intraPredMode==26 && cIdx==0 && nT<32 && !disableIntraBoundaryFilter) { |
380 | 352k | for (int y=0;y<nT;y++) { |
381 | 297k | dst[0+y*dstStride] = Clip_BitDepth(border[1] + ((border[-1-y] - border[0])>>1), bit_depth); |
382 | 297k | } |
383 | 54.9k | } |
384 | 609k | } |
385 | 1.98M | else { // intraPredAngle < 18 |
386 | | |
387 | 12.8M | for (int x=0;x<=nT;x++) |
388 | 10.8M | { ref[x] = border[-x]; } // DIFF (neg) |
389 | | |
390 | 1.98M | if (intraPredAngle<0) { |
391 | 154k | int invAngle = invAngle_table[intraPredMode-11]; |
392 | | |
393 | 154k | if ((nT*intraPredAngle)>>5 < -1) { |
394 | 396k | for (int x=(nT*intraPredAngle)>>5; x<=-1; x++) { |
395 | 306k | ref[x] = border[((x*invAngle+128)>>8)]; // DIFF (neg) |
396 | 306k | } |
397 | 90.7k | } |
398 | 1.83M | } else { |
399 | 9.91M | for (int x=nT+1; x<=2*nT;x++) { |
400 | 8.08M | ref[x] = border[-x]; // DIFF (neg) |
401 | 8.08M | } |
402 | 1.83M | } |
403 | | |
404 | 10.8M | for (int y=0;y<nT;y++) |
405 | 57.9M | for (int x=0;x<nT;x++) |
406 | 49.0M | { |
407 | 49.0M | int iIdx = ((x+1)*intraPredAngle)>>5; // DIFF (x<->y) |
408 | 49.0M | int iFact= ((x+1)*intraPredAngle)&31; // DIFF (x<->y) |
409 | | |
410 | 49.0M | if (iFact != 0) { |
411 | 16.6M | dst[x+y*dstStride] = ((32-iFact)*ref[y+iIdx+1] + iFact*ref[y+iIdx+2] + 16)>>5; // DIFF (x<->y) |
412 | 32.3M | } else { |
413 | 32.3M | dst[x+y*dstStride] = ref[y+iIdx+1]; // DIFF (x<->y) |
414 | 32.3M | } |
415 | 49.0M | } |
416 | | |
417 | 1.98M | if (intraPredMode==10 && cIdx==0 && nT<32 && !disableIntraBoundaryFilter) { // DIFF 26->10 |
418 | 147k | for (int x=0;x<nT;x++) { // DIFF (x<->y) |
419 | 123k | dst[x] = Clip_BitDepth(border[-1] + ((border[1+x] - border[0])>>1), bit_depth); // DIFF (x<->y && neg) |
420 | 123k | } |
421 | 23.5k | } |
422 | 1.98M | } |
423 | | |
424 | | |
425 | 2.59M | logtrace(LogIntraPred,"result of angular intra prediction (mode=%d):\n",intraPredMode); |
426 | | |
427 | 14.4M | for (int y=0;y<nT;y++) |
428 | 11.8M | { |
429 | 79.5M | for (int x=0;x<nT;x++) |
430 | 67.7M | logtrace(LogIntraPred,"%02x ", dst[x+y*dstStride]); |
431 | | |
432 | 11.8M | logtrace(LogIntraPred,"\n"); |
433 | 11.8M | } |
434 | 2.59M | } void intra_prediction_angular<unsigned short>(unsigned short*, int, int, bool, int, int, IntraPredMode, int, int, unsigned short*) Line | Count | Source | 338 | 994k | { | 339 | 994k | pixel_t ref_mem[4*MAX_INTRA_PRED_BLOCK_SIZE+1]; // TODO: what is the required range here ? | 340 | 994k | pixel_t* ref=&ref_mem[2*MAX_INTRA_PRED_BLOCK_SIZE]; | 341 | | | 342 | 994k | assert(intraPredMode<35); | 343 | 994k | assert(intraPredMode>=2); | 344 | | | 345 | 994k | int intraPredAngle = intraPredAngle_table[intraPredMode]; | 346 | | | 347 | 994k | if (intraPredMode >= 18) { | 348 | | | 349 | 1.65M | for (int x=0;x<=nT;x++) | 350 | 1.41M | { ref[x] = border[x]; } | 351 | | | 352 | 240k | if (intraPredAngle<0) { | 353 | 91.4k | int invAngle = invAngle_table[intraPredMode-11]; | 354 | | | 355 | 91.4k | if ((nT*intraPredAngle)>>5 < -1) { | 356 | 332k | for (int x=(nT*intraPredAngle)>>5; x<=-1; x++) { | 357 | 257k | ref[x] = border[0-((x*invAngle+128)>>8)]; | 358 | 257k | } | 359 | 74.1k | } | 360 | 148k | } else { | 361 | 878k | for (int x=nT+1; x<=2*nT;x++) { | 362 | 730k | ref[x] = border[x]; | 363 | 730k | } | 364 | 148k | } | 365 | | | 366 | 1.41M | for (int y=0;y<nT;y++) | 367 | 8.89M | for (int x=0;x<nT;x++) | 368 | 7.71M | { | 369 | 7.71M | int iIdx = ((y+1)*intraPredAngle)>>5; | 370 | 7.71M | int iFact= ((y+1)*intraPredAngle)&31; | 371 | | | 372 | 7.71M | if (iFact != 0) { | 373 | 4.68M | dst[x+y*dstStride] = ((32-iFact)*ref[x+iIdx+1] + iFact*ref[x+iIdx+2] + 16)>>5; | 374 | 4.68M | } else { | 375 | 3.03M | dst[x+y*dstStride] = ref[x+iIdx+1]; | 376 | 3.03M | } | 377 | 7.71M | } | 378 | | | 379 | 240k | if (intraPredMode==26 && cIdx==0 && nT<32 && !disableIntraBoundaryFilter) { | 380 | 188k | for (int y=0;y<nT;y++) { | 381 | 158k | dst[0+y*dstStride] = Clip_BitDepth(border[1] + ((border[-1-y] - border[0])>>1), bit_depth); | 382 | 158k | } | 383 | 29.6k | } | 384 | 240k | } | 385 | 754k | else { // intraPredAngle < 18 | 386 | | | 387 | 4.90M | for (int x=0;x<=nT;x++) | 388 | 4.15M | { ref[x] = border[-x]; } // DIFF (neg) | 389 | | | 390 | 754k | if (intraPredAngle<0) { | 391 | 58.7k | int invAngle = invAngle_table[intraPredMode-11]; | 392 | | | 393 | 58.7k | if ((nT*intraPredAngle)>>5 < -1) { | 394 | 197k | for (int x=(nT*intraPredAngle)>>5; x<=-1; x++) { | 395 | 153k | ref[x] = border[((x*invAngle+128)>>8)]; // DIFF (neg) | 396 | 153k | } | 397 | 43.7k | } | 398 | 695k | } else { | 399 | 3.80M | for (int x=nT+1; x<=2*nT;x++) { | 400 | 3.11M | ref[x] = border[-x]; // DIFF (neg) | 401 | 3.11M | } | 402 | 695k | } | 403 | | | 404 | 4.15M | for (int y=0;y<nT;y++) | 405 | 23.2M | for (int x=0;x<nT;x++) | 406 | 19.8M | { | 407 | 19.8M | int iIdx = ((x+1)*intraPredAngle)>>5; // DIFF (x<->y) | 408 | 19.8M | int iFact= ((x+1)*intraPredAngle)&31; // DIFF (x<->y) | 409 | | | 410 | 19.8M | if (iFact != 0) { | 411 | 7.16M | dst[x+y*dstStride] = ((32-iFact)*ref[y+iIdx+1] + iFact*ref[y+iIdx+2] + 16)>>5; // DIFF (x<->y) | 412 | 12.6M | } else { | 413 | 12.6M | dst[x+y*dstStride] = ref[y+iIdx+1]; // DIFF (x<->y) | 414 | 12.6M | } | 415 | 19.8M | } | 416 | | | 417 | 754k | if (intraPredMode==10 && cIdx==0 && nT<32 && !disableIntraBoundaryFilter) { // DIFF 26->10 | 418 | 80.5k | for (int x=0;x<nT;x++) { // DIFF (x<->y) | 419 | 67.4k | dst[x] = Clip_BitDepth(border[-1] + ((border[1+x] - border[0])>>1), bit_depth); // DIFF (x<->y && neg) | 420 | 67.4k | } | 421 | 13.1k | } | 422 | 754k | } | 423 | | | 424 | | | 425 | 994k | logtrace(LogIntraPred,"result of angular intra prediction (mode=%d):\n",intraPredMode); | 426 | | | 427 | 5.56M | for (int y=0;y<nT;y++) | 428 | 4.57M | { | 429 | 32.0M | for (int x=0;x<nT;x++) | 430 | 27.5M | logtrace(LogIntraPred,"%02x ", dst[x+y*dstStride]); | 431 | | | 432 | 4.57M | logtrace(LogIntraPred,"\n"); | 433 | 4.57M | } | 434 | 994k | } |
void intra_prediction_angular<unsigned char>(unsigned char*, int, int, bool, int, int, IntraPredMode, int, int, unsigned char*) Line | Count | Source | 338 | 1.59M | { | 339 | 1.59M | pixel_t ref_mem[4*MAX_INTRA_PRED_BLOCK_SIZE+1]; // TODO: what is the required range here ? | 340 | 1.59M | pixel_t* ref=&ref_mem[2*MAX_INTRA_PRED_BLOCK_SIZE]; | 341 | | | 342 | 1.59M | assert(intraPredMode<35); | 343 | 1.59M | assert(intraPredMode>=2); | 344 | | | 345 | 1.59M | int intraPredAngle = intraPredAngle_table[intraPredMode]; | 346 | | | 347 | 1.59M | if (intraPredMode >= 18) { | 348 | | | 349 | 2.51M | for (int x=0;x<=nT;x++) | 350 | 2.14M | { ref[x] = border[x]; } | 351 | | | 352 | 369k | if (intraPredAngle<0) { | 353 | 143k | int invAngle = invAngle_table[intraPredMode-11]; | 354 | | | 355 | 143k | if ((nT*intraPredAngle)>>5 < -1) { | 356 | 353k | for (int x=(nT*intraPredAngle)>>5; x<=-1; x++) { | 357 | 270k | ref[x] = border[0-((x*invAngle+128)>>8)]; | 358 | 270k | } | 359 | 82.6k | } | 360 | 225k | } else { | 361 | 1.31M | for (int x=nT+1; x<=2*nT;x++) { | 362 | 1.08M | ref[x] = border[x]; | 363 | 1.08M | } | 364 | 225k | } | 365 | | | 366 | 2.14M | for (int y=0;y<nT;y++) | 367 | 12.7M | for (int x=0;x<nT;x++) | 368 | 10.9M | { | 369 | 10.9M | int iIdx = ((y+1)*intraPredAngle)>>5; | 370 | 10.9M | int iFact= ((y+1)*intraPredAngle)&31; | 371 | | | 372 | 10.9M | if (iFact != 0) { | 373 | 7.00M | dst[x+y*dstStride] = ((32-iFact)*ref[x+iIdx+1] + iFact*ref[x+iIdx+2] + 16)>>5; | 374 | 7.00M | } else { | 375 | 3.97M | dst[x+y*dstStride] = ref[x+iIdx+1]; | 376 | 3.97M | } | 377 | 10.9M | } | 378 | | | 379 | 369k | if (intraPredMode==26 && cIdx==0 && nT<32 && !disableIntraBoundaryFilter) { | 380 | 164k | for (int y=0;y<nT;y++) { | 381 | 139k | dst[0+y*dstStride] = Clip_BitDepth(border[1] + ((border[-1-y] - border[0])>>1), bit_depth); | 382 | 139k | } | 383 | 25.3k | } | 384 | 369k | } | 385 | 1.23M | else { // intraPredAngle < 18 | 386 | | | 387 | 7.91M | for (int x=0;x<=nT;x++) | 388 | 6.68M | { ref[x] = border[-x]; } // DIFF (neg) | 389 | | | 390 | 1.23M | if (intraPredAngle<0) { | 391 | 95.8k | int invAngle = invAngle_table[intraPredMode-11]; | 392 | | | 393 | 95.8k | if ((nT*intraPredAngle)>>5 < -1) { | 394 | 199k | for (int x=(nT*intraPredAngle)>>5; x<=-1; x++) { | 395 | 152k | ref[x] = border[((x*invAngle+128)>>8)]; // DIFF (neg) | 396 | 152k | } | 397 | 46.9k | } | 398 | 1.13M | } else { | 399 | 6.11M | for (int x=nT+1; x<=2*nT;x++) { | 400 | 4.97M | ref[x] = border[-x]; // DIFF (neg) | 401 | 4.97M | } | 402 | 1.13M | } | 403 | | | 404 | 6.68M | for (int y=0;y<nT;y++) | 405 | 34.7M | for (int x=0;x<nT;x++) | 406 | 29.2M | { | 407 | 29.2M | int iIdx = ((x+1)*intraPredAngle)>>5; // DIFF (x<->y) | 408 | 29.2M | int iFact= ((x+1)*intraPredAngle)&31; // DIFF (x<->y) | 409 | | | 410 | 29.2M | if (iFact != 0) { | 411 | 9.52M | dst[x+y*dstStride] = ((32-iFact)*ref[y+iIdx+1] + iFact*ref[y+iIdx+2] + 16)>>5; // DIFF (x<->y) | 412 | 19.7M | } else { | 413 | 19.7M | dst[x+y*dstStride] = ref[y+iIdx+1]; // DIFF (x<->y) | 414 | 19.7M | } | 415 | 29.2M | } | 416 | | | 417 | 1.23M | if (intraPredMode==10 && cIdx==0 && nT<32 && !disableIntraBoundaryFilter) { // DIFF 26->10 | 418 | 66.4k | for (int x=0;x<nT;x++) { // DIFF (x<->y) | 419 | 56.0k | dst[x] = Clip_BitDepth(border[-1] + ((border[1+x] - border[0])>>1), bit_depth); // DIFF (x<->y && neg) | 420 | 56.0k | } | 421 | 10.4k | } | 422 | 1.23M | } | 423 | | | 424 | | | 425 | 1.59M | logtrace(LogIntraPred,"result of angular intra prediction (mode=%d):\n",intraPredMode); | 426 | | | 427 | 8.83M | for (int y=0;y<nT;y++) | 428 | 7.23M | { | 429 | 47.4M | for (int x=0;x<nT;x++) | 430 | 40.2M | logtrace(LogIntraPred,"%02x ", dst[x+y*dstStride]); | 431 | | | 432 | 7.23M | logtrace(LogIntraPred,"\n"); | 433 | 7.23M | } | 434 | 1.59M | } |
|
435 | | |
436 | | |
437 | | template <class pixel_t> |
438 | | void intra_border_computer<pixel_t>::preproc() |
439 | 5.68M | { |
440 | 5.68M | sps = &img->get_sps(); |
441 | 5.68M | pps = &img->get_pps(); |
442 | | |
443 | 5.68M | SubWidth = (cIdx==0) ? 1 : sps->SubWidthC; |
444 | 5.68M | SubHeight = (cIdx==0) ? 1 : sps->SubHeightC; |
445 | | |
446 | | // --- check for CTB boundaries --- |
447 | | |
448 | 5.68M | int xBLuma = xB * SubWidth; |
449 | 5.68M | int yBLuma = yB * SubHeight; |
450 | | |
451 | 5.68M | int log2CtbSize = sps->Log2CtbSizeY; |
452 | 5.68M | int picWidthInCtbs = sps->PicWidthInCtbsY; |
453 | | |
454 | | |
455 | | //printf("xB/yB: %d %d\n",xB,yB); |
456 | | |
457 | | // are we at left image border |
458 | | |
459 | 5.68M | if (xBLuma == 0) { |
460 | 93.3k | availableLeft = false; |
461 | 93.3k | availableTopLeft = false; |
462 | 93.3k | xBLuma = 0; // fake value, available flags are already set to false |
463 | 93.3k | } |
464 | | |
465 | | |
466 | | // are we at top image border |
467 | | |
468 | 5.68M | if (yBLuma == 0) { |
469 | 417k | availableTop = false; |
470 | 417k | availableTopLeft = false; |
471 | 417k | availableTopRight = false; |
472 | 417k | yBLuma = 0; // fake value, available flags are already set to false |
473 | 417k | } |
474 | | |
475 | 5.68M | if (xBLuma+nT*SubWidth >= sps->pic_width_in_luma_samples) { |
476 | 98.3k | availableTopRight=false; |
477 | 98.3k | } |
478 | | |
479 | | // check for tile and slice boundaries |
480 | | |
481 | 5.68M | int xCurrCtb = xBLuma >> log2CtbSize; |
482 | 5.68M | int yCurrCtb = yBLuma >> log2CtbSize; |
483 | 5.68M | int xLeftCtb = (xBLuma-1) >> log2CtbSize; |
484 | 5.68M | int xRightCtb = (xBLuma+nT*SubWidth) >> log2CtbSize; |
485 | 5.68M | int yTopCtb = (yBLuma-1) >> log2CtbSize; |
486 | | |
487 | 5.68M | int currCTBSlice = img->get_SliceAddrRS(xCurrCtb,yCurrCtb); |
488 | 5.68M | int leftCTBSlice = availableLeft ? img->get_SliceAddrRS(xLeftCtb, yCurrCtb) : -1; |
489 | 5.68M | int topCTBSlice = availableTop ? img->get_SliceAddrRS(xCurrCtb, yTopCtb) : -1; |
490 | 5.68M | int toprightCTBSlice = availableTopRight ? img->get_SliceAddrRS(xRightCtb, yTopCtb) : -1; |
491 | 5.68M | int topleftCTBSlice = availableTopLeft ? img->get_SliceAddrRS(xLeftCtb, yTopCtb) : -1; |
492 | | |
493 | | /* |
494 | | printf("size: %d\n",pps->TileIdRS.size()); |
495 | | printf("curr: %d left: %d top: %d\n", |
496 | | xCurrCtb+yCurrCtb*picWidthInCtbs, |
497 | | availableLeft ? xLeftCtb+yCurrCtb*picWidthInCtbs : 9999, |
498 | | availableTop ? xCurrCtb+yTopCtb*picWidthInCtbs : 9999); |
499 | | */ |
500 | 5.68M | int currCTBTileID = pps->TileIdRS[xCurrCtb+yCurrCtb*picWidthInCtbs]; |
501 | 5.68M | int leftCTBTileID = availableLeft ? pps->TileIdRS[xLeftCtb+yCurrCtb*picWidthInCtbs] : -1; |
502 | 5.68M | int topCTBTileID = availableTop ? pps->TileIdRS[xCurrCtb+yTopCtb*picWidthInCtbs] : -1; |
503 | 5.68M | int topleftCTBTileID = availableTopLeft ? pps->TileIdRS[xLeftCtb+yTopCtb*picWidthInCtbs] : -1; |
504 | 5.68M | int toprightCTBTileID= availableTopRight? pps->TileIdRS[xRightCtb+yTopCtb*picWidthInCtbs] : -1; |
505 | | |
506 | 5.68M | if (leftCTBSlice != currCTBSlice || leftCTBTileID != currCTBTileID ) availableLeft = false; |
507 | 5.68M | if (topCTBSlice != currCTBSlice || topCTBTileID != currCTBTileID ) availableTop = false; |
508 | 5.68M | if (topleftCTBSlice !=currCTBSlice||topleftCTBTileID!=currCTBTileID ) availableTopLeft = false; |
509 | 5.68M | if (toprightCTBSlice!=currCTBSlice||toprightCTBTileID!=currCTBTileID) availableTopRight= false; |
510 | | |
511 | | |
512 | | // number of pixels that are in the valid image area to the right and to the bottom |
513 | | |
514 | 5.68M | nBottom = sps->pic_height_in_luma_samples - yB*SubHeight; |
515 | 5.68M | nBottom=(nBottom+SubHeight-1)/SubHeight; |
516 | 5.68M | if (nBottom>2*nT) nBottom=2*nT; |
517 | | |
518 | 5.68M | nRight = sps->pic_width_in_luma_samples - xB*SubWidth; |
519 | 5.68M | nRight =(nRight +SubWidth-1)/SubWidth; |
520 | 5.68M | if (nRight >2*nT) nRight=2*nT; |
521 | | |
522 | 5.68M | nAvail=0; |
523 | | |
524 | 5.68M | available = &available_data[2*MAX_INTRA_PRED_BLOCK_SIZE]; |
525 | | |
526 | 5.68M | memset(available-2*nT, 0, 4*nT+1); |
527 | 5.68M | } intra_border_computer<unsigned short>::preproc() Line | Count | Source | 439 | 2.07M | { | 440 | 2.07M | sps = &img->get_sps(); | 441 | 2.07M | pps = &img->get_pps(); | 442 | | | 443 | 2.07M | SubWidth = (cIdx==0) ? 1 : sps->SubWidthC; | 444 | 2.07M | SubHeight = (cIdx==0) ? 1 : sps->SubHeightC; | 445 | | | 446 | | // --- check for CTB boundaries --- | 447 | | | 448 | 2.07M | int xBLuma = xB * SubWidth; | 449 | 2.07M | int yBLuma = yB * SubHeight; | 450 | | | 451 | 2.07M | int log2CtbSize = sps->Log2CtbSizeY; | 452 | 2.07M | int picWidthInCtbs = sps->PicWidthInCtbsY; | 453 | | | 454 | | | 455 | | //printf("xB/yB: %d %d\n",xB,yB); | 456 | | | 457 | | // are we at left image border | 458 | | | 459 | 2.07M | if (xBLuma == 0) { | 460 | 58.2k | availableLeft = false; | 461 | 58.2k | availableTopLeft = false; | 462 | 58.2k | xBLuma = 0; // fake value, available flags are already set to false | 463 | 58.2k | } | 464 | | | 465 | | | 466 | | // are we at top image border | 467 | | | 468 | 2.07M | if (yBLuma == 0) { | 469 | 177k | availableTop = false; | 470 | 177k | availableTopLeft = false; | 471 | 177k | availableTopRight = false; | 472 | 177k | yBLuma = 0; // fake value, available flags are already set to false | 473 | 177k | } | 474 | | | 475 | 2.07M | if (xBLuma+nT*SubWidth >= sps->pic_width_in_luma_samples) { | 476 | 60.8k | availableTopRight=false; | 477 | 60.8k | } | 478 | | | 479 | | // check for tile and slice boundaries | 480 | | | 481 | 2.07M | int xCurrCtb = xBLuma >> log2CtbSize; | 482 | 2.07M | int yCurrCtb = yBLuma >> log2CtbSize; | 483 | 2.07M | int xLeftCtb = (xBLuma-1) >> log2CtbSize; | 484 | 2.07M | int xRightCtb = (xBLuma+nT*SubWidth) >> log2CtbSize; | 485 | 2.07M | int yTopCtb = (yBLuma-1) >> log2CtbSize; | 486 | | | 487 | 2.07M | int currCTBSlice = img->get_SliceAddrRS(xCurrCtb,yCurrCtb); | 488 | 2.07M | int leftCTBSlice = availableLeft ? img->get_SliceAddrRS(xLeftCtb, yCurrCtb) : -1; | 489 | 2.07M | int topCTBSlice = availableTop ? img->get_SliceAddrRS(xCurrCtb, yTopCtb) : -1; | 490 | 2.07M | int toprightCTBSlice = availableTopRight ? img->get_SliceAddrRS(xRightCtb, yTopCtb) : -1; | 491 | 2.07M | int topleftCTBSlice = availableTopLeft ? img->get_SliceAddrRS(xLeftCtb, yTopCtb) : -1; | 492 | | | 493 | | /* | 494 | | printf("size: %d\n",pps->TileIdRS.size()); | 495 | | printf("curr: %d left: %d top: %d\n", | 496 | | xCurrCtb+yCurrCtb*picWidthInCtbs, | 497 | | availableLeft ? xLeftCtb+yCurrCtb*picWidthInCtbs : 9999, | 498 | | availableTop ? xCurrCtb+yTopCtb*picWidthInCtbs : 9999); | 499 | | */ | 500 | 2.07M | int currCTBTileID = pps->TileIdRS[xCurrCtb+yCurrCtb*picWidthInCtbs]; | 501 | 2.07M | int leftCTBTileID = availableLeft ? pps->TileIdRS[xLeftCtb+yCurrCtb*picWidthInCtbs] : -1; | 502 | 2.07M | int topCTBTileID = availableTop ? pps->TileIdRS[xCurrCtb+yTopCtb*picWidthInCtbs] : -1; | 503 | 2.07M | int topleftCTBTileID = availableTopLeft ? pps->TileIdRS[xLeftCtb+yTopCtb*picWidthInCtbs] : -1; | 504 | 2.07M | int toprightCTBTileID= availableTopRight? pps->TileIdRS[xRightCtb+yTopCtb*picWidthInCtbs] : -1; | 505 | | | 506 | 2.07M | if (leftCTBSlice != currCTBSlice || leftCTBTileID != currCTBTileID ) availableLeft = false; | 507 | 2.07M | if (topCTBSlice != currCTBSlice || topCTBTileID != currCTBTileID ) availableTop = false; | 508 | 2.07M | if (topleftCTBSlice !=currCTBSlice||topleftCTBTileID!=currCTBTileID ) availableTopLeft = false; | 509 | 2.07M | if (toprightCTBSlice!=currCTBSlice||toprightCTBTileID!=currCTBTileID) availableTopRight= false; | 510 | | | 511 | | | 512 | | // number of pixels that are in the valid image area to the right and to the bottom | 513 | | | 514 | 2.07M | nBottom = sps->pic_height_in_luma_samples - yB*SubHeight; | 515 | 2.07M | nBottom=(nBottom+SubHeight-1)/SubHeight; | 516 | 2.07M | if (nBottom>2*nT) nBottom=2*nT; | 517 | | | 518 | 2.07M | nRight = sps->pic_width_in_luma_samples - xB*SubWidth; | 519 | 2.07M | nRight =(nRight +SubWidth-1)/SubWidth; | 520 | 2.07M | if (nRight >2*nT) nRight=2*nT; | 521 | | | 522 | 2.07M | nAvail=0; | 523 | | | 524 | 2.07M | available = &available_data[2*MAX_INTRA_PRED_BLOCK_SIZE]; | 525 | | | 526 | 2.07M | memset(available-2*nT, 0, 4*nT+1); | 527 | 2.07M | } |
intra_border_computer<unsigned char>::preproc() Line | Count | Source | 439 | 3.61M | { | 440 | 3.61M | sps = &img->get_sps(); | 441 | 3.61M | pps = &img->get_pps(); | 442 | | | 443 | 3.61M | SubWidth = (cIdx==0) ? 1 : sps->SubWidthC; | 444 | 3.61M | SubHeight = (cIdx==0) ? 1 : sps->SubHeightC; | 445 | | | 446 | | // --- check for CTB boundaries --- | 447 | | | 448 | 3.61M | int xBLuma = xB * SubWidth; | 449 | 3.61M | int yBLuma = yB * SubHeight; | 450 | | | 451 | 3.61M | int log2CtbSize = sps->Log2CtbSizeY; | 452 | 3.61M | int picWidthInCtbs = sps->PicWidthInCtbsY; | 453 | | | 454 | | | 455 | | //printf("xB/yB: %d %d\n",xB,yB); | 456 | | | 457 | | // are we at left image border | 458 | | | 459 | 3.61M | if (xBLuma == 0) { | 460 | 35.1k | availableLeft = false; | 461 | 35.1k | availableTopLeft = false; | 462 | 35.1k | xBLuma = 0; // fake value, available flags are already set to false | 463 | 35.1k | } | 464 | | | 465 | | | 466 | | // are we at top image border | 467 | | | 468 | 3.61M | if (yBLuma == 0) { | 469 | 240k | availableTop = false; | 470 | 240k | availableTopLeft = false; | 471 | 240k | availableTopRight = false; | 472 | 240k | yBLuma = 0; // fake value, available flags are already set to false | 473 | 240k | } | 474 | | | 475 | 3.61M | if (xBLuma+nT*SubWidth >= sps->pic_width_in_luma_samples) { | 476 | 37.4k | availableTopRight=false; | 477 | 37.4k | } | 478 | | | 479 | | // check for tile and slice boundaries | 480 | | | 481 | 3.61M | int xCurrCtb = xBLuma >> log2CtbSize; | 482 | 3.61M | int yCurrCtb = yBLuma >> log2CtbSize; | 483 | 3.61M | int xLeftCtb = (xBLuma-1) >> log2CtbSize; | 484 | 3.61M | int xRightCtb = (xBLuma+nT*SubWidth) >> log2CtbSize; | 485 | 3.61M | int yTopCtb = (yBLuma-1) >> log2CtbSize; | 486 | | | 487 | 3.61M | int currCTBSlice = img->get_SliceAddrRS(xCurrCtb,yCurrCtb); | 488 | 3.61M | int leftCTBSlice = availableLeft ? img->get_SliceAddrRS(xLeftCtb, yCurrCtb) : -1; | 489 | 3.61M | int topCTBSlice = availableTop ? img->get_SliceAddrRS(xCurrCtb, yTopCtb) : -1; | 490 | 3.61M | int toprightCTBSlice = availableTopRight ? img->get_SliceAddrRS(xRightCtb, yTopCtb) : -1; | 491 | 3.61M | int topleftCTBSlice = availableTopLeft ? img->get_SliceAddrRS(xLeftCtb, yTopCtb) : -1; | 492 | | | 493 | | /* | 494 | | printf("size: %d\n",pps->TileIdRS.size()); | 495 | | printf("curr: %d left: %d top: %d\n", | 496 | | xCurrCtb+yCurrCtb*picWidthInCtbs, | 497 | | availableLeft ? xLeftCtb+yCurrCtb*picWidthInCtbs : 9999, | 498 | | availableTop ? xCurrCtb+yTopCtb*picWidthInCtbs : 9999); | 499 | | */ | 500 | 3.61M | int currCTBTileID = pps->TileIdRS[xCurrCtb+yCurrCtb*picWidthInCtbs]; | 501 | 3.61M | int leftCTBTileID = availableLeft ? pps->TileIdRS[xLeftCtb+yCurrCtb*picWidthInCtbs] : -1; | 502 | 3.61M | int topCTBTileID = availableTop ? pps->TileIdRS[xCurrCtb+yTopCtb*picWidthInCtbs] : -1; | 503 | 3.61M | int topleftCTBTileID = availableTopLeft ? pps->TileIdRS[xLeftCtb+yTopCtb*picWidthInCtbs] : -1; | 504 | 3.61M | int toprightCTBTileID= availableTopRight? pps->TileIdRS[xRightCtb+yTopCtb*picWidthInCtbs] : -1; | 505 | | | 506 | 3.61M | if (leftCTBSlice != currCTBSlice || leftCTBTileID != currCTBTileID ) availableLeft = false; | 507 | 3.61M | if (topCTBSlice != currCTBSlice || topCTBTileID != currCTBTileID ) availableTop = false; | 508 | 3.61M | if (topleftCTBSlice !=currCTBSlice||topleftCTBTileID!=currCTBTileID ) availableTopLeft = false; | 509 | 3.61M | if (toprightCTBSlice!=currCTBSlice||toprightCTBTileID!=currCTBTileID) availableTopRight= false; | 510 | | | 511 | | | 512 | | // number of pixels that are in the valid image area to the right and to the bottom | 513 | | | 514 | 3.61M | nBottom = sps->pic_height_in_luma_samples - yB*SubHeight; | 515 | 3.61M | nBottom=(nBottom+SubHeight-1)/SubHeight; | 516 | 3.61M | if (nBottom>2*nT) nBottom=2*nT; | 517 | | | 518 | 3.61M | nRight = sps->pic_width_in_luma_samples - xB*SubWidth; | 519 | 3.61M | nRight =(nRight +SubWidth-1)/SubWidth; | 520 | 3.61M | if (nRight >2*nT) nRight=2*nT; | 521 | | | 522 | 3.61M | nAvail=0; | 523 | | | 524 | 3.61M | available = &available_data[2*MAX_INTRA_PRED_BLOCK_SIZE]; | 525 | | | 526 | 3.61M | memset(available-2*nT, 0, 4*nT+1); | 527 | 3.61M | } |
|
528 | | |
529 | | |
530 | | template <class pixel_t> |
531 | | void intra_border_computer<pixel_t>::fill_from_image() |
532 | 5.68M | { |
533 | 5.68M | assert(nT<=32); |
534 | | |
535 | 5.68M | pixel_t* image; |
536 | 5.68M | int stride; |
537 | 5.68M | image = (pixel_t*)img->get_image_plane(cIdx); |
538 | 5.68M | stride = img->get_image_stride(cIdx); |
539 | | |
540 | 5.68M | int xBLuma = xB * SubWidth; |
541 | 5.68M | int yBLuma = yB * SubHeight; |
542 | | |
543 | 5.68M | int currBlockAddr = pps->MinTbAddrZS[ (xBLuma>>sps->Log2MinTrafoSize) + |
544 | 5.68M | (yBLuma>>sps->Log2MinTrafoSize) * sps->PicWidthInTbsY ]; |
545 | | |
546 | | |
547 | | // copy pixels at left column |
548 | | |
549 | 18.0M | for (int y=nBottom-1 ; y>=0 ; y-=4) |
550 | 12.4M | if (availableLeft) |
551 | 12.1M | { |
552 | 12.1M | int NBlockAddr = pps->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) + |
553 | 12.1M | (((yB+y)*SubHeight)>>sps->Log2MinTrafoSize) |
554 | 12.1M | * sps->PicWidthInTbsY ]; |
555 | | |
556 | 12.1M | bool availableN = NBlockAddr <= currBlockAddr; |
557 | | |
558 | 12.1M | if (pps->constrained_intra_pred_flag) { |
559 | 1.37M | if (img->get_pred_mode((xB-1)*SubWidth,(yB+y)*SubHeight)!=MODE_INTRA) |
560 | 37.5k | availableN = false; |
561 | 1.37M | } |
562 | | |
563 | 12.1M | if (availableN) { |
564 | 9.16M | if (!nAvail) firstValue = image[xB-1 + (yB+y)*stride]; |
565 | | |
566 | 45.8M | for (int i=0;i<4;i++) { |
567 | 36.6M | available[-y+i-1] = availableN; |
568 | 36.6M | out_border[-y+i-1] = image[xB-1 + (yB+y-i)*stride]; |
569 | 36.6M | } |
570 | | |
571 | 9.16M | nAvail+=4; |
572 | 9.16M | } |
573 | 12.1M | } |
574 | | |
575 | | // copy pixel at top-left position |
576 | | |
577 | 5.68M | if (availableTopLeft) |
578 | 5.17M | { |
579 | 5.17M | int NBlockAddr = pps->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) + |
580 | 5.17M | (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize) |
581 | 5.17M | * sps->PicWidthInTbsY ]; |
582 | | |
583 | 5.17M | bool availableN = NBlockAddr <= currBlockAddr; |
584 | | |
585 | 5.17M | if (pps->constrained_intra_pred_flag) { |
586 | 577k | if (img->get_pred_mode((xB-1)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) { |
587 | 22.0k | availableN = false; |
588 | 22.0k | } |
589 | 577k | } |
590 | | |
591 | 5.17M | if (availableN) { |
592 | 5.14M | if (!nAvail) firstValue = image[xB-1 + (yB-1)*stride]; |
593 | | |
594 | 5.14M | out_border[0] = image[xB-1 + (yB-1)*stride]; |
595 | 5.14M | available[0] = availableN; |
596 | 5.14M | nAvail++; |
597 | 5.14M | } |
598 | 5.17M | } |
599 | | |
600 | | // copy pixels at top row |
601 | | |
602 | 18.2M | for (int x=0 ; x<nRight ; x+=4) { |
603 | 12.5M | bool borderAvailable; |
604 | 12.5M | if (x<nT) borderAvailable=availableTop; |
605 | 6.24M | else borderAvailable=availableTopRight; |
606 | | |
607 | 12.5M | if (borderAvailable) |
608 | 11.4M | { |
609 | 11.4M | int NBlockAddr = pps->MinTbAddrZS[ (((xB+x)*SubWidth )>>sps->Log2MinTrafoSize) + |
610 | 11.4M | (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize) |
611 | 11.4M | * sps->PicWidthInTbsY ]; |
612 | | |
613 | 11.4M | bool availableN = NBlockAddr <= currBlockAddr; |
614 | | |
615 | 11.4M | if (pps->constrained_intra_pred_flag) { |
616 | 1.37M | if (img->get_pred_mode((xB+x)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) { |
617 | 36.4k | availableN = false; |
618 | 36.4k | } |
619 | 1.37M | } |
620 | | |
621 | | |
622 | 11.4M | if (availableN) { |
623 | 8.60M | if (!nAvail) firstValue = image[xB+x + (yB-1)*stride]; |
624 | | |
625 | 43.0M | for (int i=0;i<4;i++) { |
626 | 34.4M | out_border[x+i+1] = image[xB+x+i + (yB-1)*stride]; |
627 | 34.4M | available[x+i+1] = availableN; |
628 | 34.4M | } |
629 | | |
630 | 8.60M | nAvail+=4; |
631 | 8.60M | } |
632 | 11.4M | } |
633 | 12.5M | } |
634 | 5.68M | } intra_border_computer<unsigned short>::fill_from_image() Line | Count | Source | 532 | 2.07M | { | 533 | 2.07M | assert(nT<=32); | 534 | | | 535 | 2.07M | pixel_t* image; | 536 | 2.07M | int stride; | 537 | 2.07M | image = (pixel_t*)img->get_image_plane(cIdx); | 538 | 2.07M | stride = img->get_image_stride(cIdx); | 539 | | | 540 | 2.07M | int xBLuma = xB * SubWidth; | 541 | 2.07M | int yBLuma = yB * SubHeight; | 542 | | | 543 | 2.07M | int currBlockAddr = pps->MinTbAddrZS[ (xBLuma>>sps->Log2MinTrafoSize) + | 544 | 2.07M | (yBLuma>>sps->Log2MinTrafoSize) * sps->PicWidthInTbsY ]; | 545 | | | 546 | | | 547 | | // copy pixels at left column | 548 | | | 549 | 6.59M | for (int y=nBottom-1 ; y>=0 ; y-=4) | 550 | 4.51M | if (availableLeft) | 551 | 4.38M | { | 552 | 4.38M | int NBlockAddr = pps->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) + | 553 | 4.38M | (((yB+y)*SubHeight)>>sps->Log2MinTrafoSize) | 554 | 4.38M | * sps->PicWidthInTbsY ]; | 555 | | | 556 | 4.38M | bool availableN = NBlockAddr <= currBlockAddr; | 557 | | | 558 | 4.38M | if (pps->constrained_intra_pred_flag) { | 559 | 362k | if (img->get_pred_mode((xB-1)*SubWidth,(yB+y)*SubHeight)!=MODE_INTRA) | 560 | 17.5k | availableN = false; | 561 | 362k | } | 562 | | | 563 | 4.38M | if (availableN) { | 564 | 3.29M | if (!nAvail) firstValue = image[xB-1 + (yB+y)*stride]; | 565 | | | 566 | 16.4M | for (int i=0;i<4;i++) { | 567 | 13.1M | available[-y+i-1] = availableN; | 568 | 13.1M | out_border[-y+i-1] = image[xB-1 + (yB+y-i)*stride]; | 569 | 13.1M | } | 570 | | | 571 | 3.29M | nAvail+=4; | 572 | 3.29M | } | 573 | 4.38M | } | 574 | | | 575 | | // copy pixel at top-left position | 576 | | | 577 | 2.07M | if (availableTopLeft) | 578 | 1.83M | { | 579 | 1.83M | int NBlockAddr = pps->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) + | 580 | 1.83M | (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize) | 581 | 1.83M | * sps->PicWidthInTbsY ]; | 582 | | | 583 | 1.83M | bool availableN = NBlockAddr <= currBlockAddr; | 584 | | | 585 | 1.83M | if (pps->constrained_intra_pred_flag) { | 586 | 169k | if (img->get_pred_mode((xB-1)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) { | 587 | 13.1k | availableN = false; | 588 | 13.1k | } | 589 | 169k | } | 590 | | | 591 | 1.83M | if (availableN) { | 592 | 1.82M | if (!nAvail) firstValue = image[xB-1 + (yB-1)*stride]; | 593 | | | 594 | 1.82M | out_border[0] = image[xB-1 + (yB-1)*stride]; | 595 | 1.82M | available[0] = availableN; | 596 | 1.82M | nAvail++; | 597 | 1.82M | } | 598 | 1.83M | } | 599 | | | 600 | | // copy pixels at top row | 601 | | | 602 | 6.65M | for (int x=0 ; x<nRight ; x+=4) { | 603 | 4.57M | bool borderAvailable; | 604 | 4.57M | if (x<nT) borderAvailable=availableTop; | 605 | 2.25M | else borderAvailable=availableTopRight; | 606 | | | 607 | 4.57M | if (borderAvailable) | 608 | 4.08M | { | 609 | 4.08M | int NBlockAddr = pps->MinTbAddrZS[ (((xB+x)*SubWidth )>>sps->Log2MinTrafoSize) + | 610 | 4.08M | (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize) | 611 | 4.08M | * sps->PicWidthInTbsY ]; | 612 | | | 613 | 4.08M | bool availableN = NBlockAddr <= currBlockAddr; | 614 | | | 615 | 4.08M | if (pps->constrained_intra_pred_flag) { | 616 | 392k | if (img->get_pred_mode((xB+x)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) { | 617 | 20.5k | availableN = false; | 618 | 20.5k | } | 619 | 392k | } | 620 | | | 621 | | | 622 | 4.08M | if (availableN) { | 623 | 3.08M | if (!nAvail) firstValue = image[xB+x + (yB-1)*stride]; | 624 | | | 625 | 15.4M | for (int i=0;i<4;i++) { | 626 | 12.3M | out_border[x+i+1] = image[xB+x+i + (yB-1)*stride]; | 627 | 12.3M | available[x+i+1] = availableN; | 628 | 12.3M | } | 629 | | | 630 | 3.08M | nAvail+=4; | 631 | 3.08M | } | 632 | 4.08M | } | 633 | 4.57M | } | 634 | 2.07M | } |
intra_border_computer<unsigned char>::fill_from_image() Line | Count | Source | 532 | 3.61M | { | 533 | 3.61M | assert(nT<=32); | 534 | | | 535 | 3.61M | pixel_t* image; | 536 | 3.61M | int stride; | 537 | 3.61M | image = (pixel_t*)img->get_image_plane(cIdx); | 538 | 3.61M | stride = img->get_image_stride(cIdx); | 539 | | | 540 | 3.61M | int xBLuma = xB * SubWidth; | 541 | 3.61M | int yBLuma = yB * SubHeight; | 542 | | | 543 | 3.61M | int currBlockAddr = pps->MinTbAddrZS[ (xBLuma>>sps->Log2MinTrafoSize) + | 544 | 3.61M | (yBLuma>>sps->Log2MinTrafoSize) * sps->PicWidthInTbsY ]; | 545 | | | 546 | | | 547 | | // copy pixels at left column | 548 | | | 549 | 11.5M | for (int y=nBottom-1 ; y>=0 ; y-=4) | 550 | 7.89M | if (availableLeft) | 551 | 7.80M | { | 552 | 7.80M | int NBlockAddr = pps->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) + | 553 | 7.80M | (((yB+y)*SubHeight)>>sps->Log2MinTrafoSize) | 554 | 7.80M | * sps->PicWidthInTbsY ]; | 555 | | | 556 | 7.80M | bool availableN = NBlockAddr <= currBlockAddr; | 557 | | | 558 | 7.80M | if (pps->constrained_intra_pred_flag) { | 559 | 1.00M | if (img->get_pred_mode((xB-1)*SubWidth,(yB+y)*SubHeight)!=MODE_INTRA) | 560 | 20.0k | availableN = false; | 561 | 1.00M | } | 562 | | | 563 | 7.80M | if (availableN) { | 564 | 5.87M | if (!nAvail) firstValue = image[xB-1 + (yB+y)*stride]; | 565 | | | 566 | 29.3M | for (int i=0;i<4;i++) { | 567 | 23.4M | available[-y+i-1] = availableN; | 568 | 23.4M | out_border[-y+i-1] = image[xB-1 + (yB+y-i)*stride]; | 569 | 23.4M | } | 570 | | | 571 | 5.87M | nAvail+=4; | 572 | 5.87M | } | 573 | 7.80M | } | 574 | | | 575 | | // copy pixel at top-left position | 576 | | | 577 | 3.61M | if (availableTopLeft) | 578 | 3.33M | { | 579 | 3.33M | int NBlockAddr = pps->MinTbAddrZS[ (((xB-1)*SubWidth )>>sps->Log2MinTrafoSize) + | 580 | 3.33M | (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize) | 581 | 3.33M | * sps->PicWidthInTbsY ]; | 582 | | | 583 | 3.33M | bool availableN = NBlockAddr <= currBlockAddr; | 584 | | | 585 | 3.33M | if (pps->constrained_intra_pred_flag) { | 586 | 408k | if (img->get_pred_mode((xB-1)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) { | 587 | 8.88k | availableN = false; | 588 | 8.88k | } | 589 | 408k | } | 590 | | | 591 | 3.33M | if (availableN) { | 592 | 3.32M | if (!nAvail) firstValue = image[xB-1 + (yB-1)*stride]; | 593 | | | 594 | 3.32M | out_border[0] = image[xB-1 + (yB-1)*stride]; | 595 | 3.32M | available[0] = availableN; | 596 | 3.32M | nAvail++; | 597 | 3.32M | } | 598 | 3.33M | } | 599 | | | 600 | | // copy pixels at top row | 601 | | | 602 | 11.6M | for (int x=0 ; x<nRight ; x+=4) { | 603 | 8.01M | bool borderAvailable; | 604 | 8.01M | if (x<nT) borderAvailable=availableTop; | 605 | 3.98M | else borderAvailable=availableTopRight; | 606 | | | 607 | 8.01M | if (borderAvailable) | 608 | 7.35M | { | 609 | 7.35M | int NBlockAddr = pps->MinTbAddrZS[ (((xB+x)*SubWidth )>>sps->Log2MinTrafoSize) + | 610 | 7.35M | (((yB-1)*SubHeight)>>sps->Log2MinTrafoSize) | 611 | 7.35M | * sps->PicWidthInTbsY ]; | 612 | | | 613 | 7.35M | bool availableN = NBlockAddr <= currBlockAddr; | 614 | | | 615 | 7.35M | if (pps->constrained_intra_pred_flag) { | 616 | 986k | if (img->get_pred_mode((xB+x)*SubWidth,(yB-1)*SubHeight)!=MODE_INTRA) { | 617 | 15.8k | availableN = false; | 618 | 15.8k | } | 619 | 986k | } | 620 | | | 621 | | | 622 | 7.35M | if (availableN) { | 623 | 5.51M | if (!nAvail) firstValue = image[xB+x + (yB-1)*stride]; | 624 | | | 625 | 27.5M | for (int i=0;i<4;i++) { | 626 | 22.0M | out_border[x+i+1] = image[xB+x+i + (yB-1)*stride]; | 627 | 22.0M | available[x+i+1] = availableN; | 628 | 22.0M | } | 629 | | | 630 | 5.51M | nAvail+=4; | 631 | 5.51M | } | 632 | 7.35M | } | 633 | 8.01M | } | 634 | 3.61M | } |
|
635 | | |
636 | | |
637 | | |
638 | | template <class pixel_t> |
639 | | void intra_border_computer<pixel_t>::reference_sample_substitution() |
640 | 5.68M | { |
641 | | // reference sample substitution |
642 | | |
643 | 5.68M | const int bit_depth = img->get_bit_depth(cIdx); |
644 | | |
645 | 5.68M | if (nAvail!=4*nT+1) { |
646 | 4.09M | if (nAvail==0) { |
647 | 11.2k | if (sizeof(pixel_t)==1) { |
648 | 4.88k | memset(out_border-2*nT, 1<<(bit_depth-1), 4*nT+1); |
649 | 4.88k | } |
650 | 6.39k | else { |
651 | 141k | for (int i = -2*nT; i <= 2*nT ; i++) { |
652 | 135k | out_border[i] = 1<<(bit_depth-1); |
653 | 135k | } |
654 | 6.39k | } |
655 | 11.2k | } |
656 | 4.08M | else { |
657 | 4.08M | if (!available[-2*nT]) { |
658 | 2.97M | out_border[-2*nT] = firstValue; |
659 | 2.97M | } |
660 | | |
661 | 78.0M | for (int i=-2*nT+1; i<=2*nT; i++) |
662 | 74.0M | if (!available[i]) { |
663 | 27.7M | out_border[i]=out_border[i-1]; |
664 | 27.7M | } |
665 | 4.08M | } |
666 | 4.09M | } |
667 | | |
668 | 5.68M | logtrace(LogIntraPred,"availableN: "); |
669 | 5.68M | print_border(available,NULL,nT); |
670 | 5.68M | logtrace(LogIntraPred,"\n"); |
671 | | |
672 | 5.68M | logtrace(LogIntraPred,"output: "); |
673 | 5.68M | print_border(out_border,NULL,nT); |
674 | 5.68M | logtrace(LogIntraPred,"\n"); |
675 | 5.68M | } intra_border_computer<unsigned short>::reference_sample_substitution() Line | Count | Source | 640 | 2.07M | { | 641 | | // reference sample substitution | 642 | | | 643 | 2.07M | const int bit_depth = img->get_bit_depth(cIdx); | 644 | | | 645 | 2.07M | if (nAvail!=4*nT+1) { | 646 | 1.51M | if (nAvail==0) { | 647 | 6.39k | if (sizeof(pixel_t)==1) { | 648 | 0 | memset(out_border-2*nT, 1<<(bit_depth-1), 4*nT+1); | 649 | 0 | } | 650 | 6.39k | else { | 651 | 141k | for (int i = -2*nT; i <= 2*nT ; i++) { | 652 | 135k | out_border[i] = 1<<(bit_depth-1); | 653 | 135k | } | 654 | 6.39k | } | 655 | 6.39k | } | 656 | 1.51M | else { | 657 | 1.51M | if (!available[-2*nT]) { | 658 | 1.10M | out_border[-2*nT] = firstValue; | 659 | 1.10M | } | 660 | | | 661 | 29.0M | for (int i=-2*nT+1; i<=2*nT; i++) | 662 | 27.5M | if (!available[i]) { | 663 | 10.5M | out_border[i]=out_border[i-1]; | 664 | 10.5M | } | 665 | 1.51M | } | 666 | 1.51M | } | 667 | | | 668 | 2.07M | logtrace(LogIntraPred,"availableN: "); | 669 | 2.07M | print_border(available,NULL,nT); | 670 | 2.07M | logtrace(LogIntraPred,"\n"); | 671 | | | 672 | 2.07M | logtrace(LogIntraPred,"output: "); | 673 | 2.07M | print_border(out_border,NULL,nT); | 674 | 2.07M | logtrace(LogIntraPred,"\n"); | 675 | 2.07M | } |
intra_border_computer<unsigned char>::reference_sample_substitution() Line | Count | Source | 640 | 3.61M | { | 641 | | // reference sample substitution | 642 | | | 643 | 3.61M | const int bit_depth = img->get_bit_depth(cIdx); | 644 | | | 645 | 3.61M | if (nAvail!=4*nT+1) { | 646 | 2.57M | if (nAvail==0) { | 647 | 4.88k | if (sizeof(pixel_t)==1) { | 648 | 4.88k | memset(out_border-2*nT, 1<<(bit_depth-1), 4*nT+1); | 649 | 4.88k | } | 650 | 0 | else { | 651 | 0 | for (int i = -2*nT; i <= 2*nT ; i++) { | 652 | 0 | out_border[i] = 1<<(bit_depth-1); | 653 | 0 | } | 654 | 0 | } | 655 | 4.88k | } | 656 | 2.57M | else { | 657 | 2.57M | if (!available[-2*nT]) { | 658 | 1.86M | out_border[-2*nT] = firstValue; | 659 | 1.86M | } | 660 | | | 661 | 49.0M | for (int i=-2*nT+1; i<=2*nT; i++) | 662 | 46.4M | if (!available[i]) { | 663 | 17.1M | out_border[i]=out_border[i-1]; | 664 | 17.1M | } | 665 | 2.57M | } | 666 | 2.57M | } | 667 | | | 668 | 3.61M | logtrace(LogIntraPred,"availableN: "); | 669 | 3.61M | print_border(available,NULL,nT); | 670 | 3.61M | logtrace(LogIntraPred,"\n"); | 671 | | | 672 | 3.61M | logtrace(LogIntraPred,"output: "); | 673 | 3.61M | print_border(out_border,NULL,nT); | 674 | 3.61M | logtrace(LogIntraPred,"\n"); | 675 | 3.61M | } |
|
676 | | |
677 | | |
678 | | #endif |