]> git.sesse.net Git - ffmpeg/blob - libavcodec/hevcdsp_template.c
Merge commit 'bb789016d423d2cfacd2904ac66257bdf7f0964e'
[ffmpeg] / libavcodec / hevcdsp_template.c
1 /*
2  * HEVC video decoder
3  *
4  * Copyright (C) 2012 - 2013 Guillaume Martres
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include "get_bits.h"
24 #include "hevc.h"
25
26 #include "bit_depth_template.c"
27 #include "hevcdsp.h"
28
29
30 static void FUNC(put_pcm)(uint8_t *_dst, ptrdiff_t stride, int width, int height,
31                           GetBitContext *gb, int pcm_bit_depth)
32 {
33     int x, y;
34     pixel *dst = (pixel *)_dst;
35
36     stride /= sizeof(pixel);
37
38     for (y = 0; y < height; y++) {
39         for (x = 0; x < width; x++)
40             dst[x] = get_bits(gb, pcm_bit_depth) << (BIT_DEPTH - pcm_bit_depth);
41         dst += stride;
42     }
43 }
44
45 static void FUNC(transform_add4x4)(uint8_t *_dst, int16_t *coeffs,
46                                        ptrdiff_t stride)
47 {
48     int x, y;
49     pixel *dst = (pixel *)_dst;
50
51     stride /= sizeof(pixel);
52
53     for (y = 0; y < 4; y++) {
54         for (x = 0; x < 4; x++) {
55             dst[x] = av_clip_pixel(dst[x] + *coeffs);
56             coeffs++;
57         }
58         dst += stride;
59     }
60 }
61
62 static void FUNC(transform_add8x8)(uint8_t *_dst, int16_t *coeffs,
63                                        ptrdiff_t stride)
64 {
65     int x, y;
66     pixel *dst = (pixel *)_dst;
67
68     stride /= sizeof(pixel);
69
70     for (y = 0; y < 8; y++) {
71         for (x = 0; x < 8; x++) {
72             dst[x] = av_clip_pixel(dst[x] + *coeffs);
73             coeffs++;
74         }
75         dst += stride;
76     }
77 }
78
79 static void FUNC(transform_add16x16)(uint8_t *_dst, int16_t *coeffs,
80                                          ptrdiff_t stride)
81 {
82     int x, y;
83     pixel *dst = (pixel *)_dst;
84
85     stride /= sizeof(pixel);
86
87     for (y = 0; y < 16; y++) {
88         for (x = 0; x < 16; x++) {
89             dst[x] = av_clip_pixel(dst[x] + *coeffs);
90             coeffs++;
91         }
92         dst += stride;
93     }
94 }
95
96 static void FUNC(transform_add32x32)(uint8_t *_dst, int16_t *coeffs,
97                                          ptrdiff_t stride)
98 {
99     int x, y;
100     pixel *dst = (pixel *)_dst;
101
102     stride /= sizeof(pixel);
103
104     for (y = 0; y < 32; y++) {
105         for (x = 0; x < 32; x++) {
106             dst[x] = av_clip_pixel(dst[x] + *coeffs);
107             coeffs++;
108         }
109         dst += stride;
110     }
111 }
112
113
114 static void FUNC(transform_rdpcm)(int16_t *_coeffs, int16_t log2_size, int mode)
115 {
116     int16_t *coeffs = (int16_t *) _coeffs;
117     int x, y;
118     int size = 1 << log2_size;
119
120     if (mode) {
121         coeffs += size;
122         for (y = 0; y < size - 1; y++) {
123             for (x = 0; x < size; x++)
124                 coeffs[x] += coeffs[x - size];
125             coeffs += size;
126         }
127     } else {
128         for (y = 0; y < size; y++) {
129             for (x = 1; x < size; x++)
130                 coeffs[x] += coeffs[x - 1];
131             coeffs += size;
132         }
133     }
134 }
135
136 static void FUNC(transform_skip)(int16_t *_coeffs, int16_t log2_size)
137 {
138     int shift  = 15 - BIT_DEPTH - log2_size;
139     int x, y;
140     int size = 1 << log2_size;
141     int16_t *coeffs = _coeffs;
142
143
144     if (shift > 0) {
145         int offset = 1 << (shift - 1);
146         for (y = 0; y < size; y++) {
147             for (x = 0; x < size; x++) {
148                 *coeffs = (*coeffs + offset) >> shift;
149                 coeffs++;
150             }
151         }
152     } else {
153         for (y = 0; y < size; y++) {
154             for (x = 0; x < size; x++) {
155                 *coeffs = *coeffs << -shift;
156                 coeffs++;
157             }
158         }
159     }
160 }
161
162 #define SET(dst, x)   (dst) = (x)
163 #define SCALE(dst, x) (dst) = av_clip_int16(((x) + add) >> shift)
164 #define ADD_AND_SCALE(dst, x)                                           \
165     (dst) = av_clip_pixel((dst) + av_clip_int16(((x) + add) >> shift))
166
167 #define TR_4x4_LUMA(dst, src, step, assign)                             \
168     do {                                                                \
169         int c0 = src[0 * step] + src[2 * step];                         \
170         int c1 = src[2 * step] + src[3 * step];                         \
171         int c2 = src[0 * step] - src[3 * step];                         \
172         int c3 = 74 * src[1 * step];                                    \
173                                                                         \
174         assign(dst[2 * step], 74 * (src[0 * step] -                     \
175                                     src[2 * step] +                     \
176                                     src[3 * step]));                    \
177         assign(dst[0 * step], 29 * c0 + 55 * c1 + c3);                  \
178         assign(dst[1 * step], 55 * c2 - 29 * c1 + c3);                  \
179         assign(dst[3 * step], 55 * c0 + 29 * c2 - c3);                  \
180     } while (0)
181
182 static void FUNC(transform_4x4_luma)(int16_t *coeffs)
183 {
184     int i;
185     int shift    = 7;
186     int add      = 1 << (shift - 1);
187     int16_t *src = coeffs;
188
189     for (i = 0; i < 4; i++) {
190         TR_4x4_LUMA(src, src, 4, SCALE);
191         src++;
192     }
193
194     shift = 20 - BIT_DEPTH;
195     add   = 1 << (shift - 1);
196     for (i = 0; i < 4; i++) {
197         TR_4x4_LUMA(coeffs, coeffs, 1, SCALE);
198         coeffs += 4;
199     }
200 }
201
202 #undef TR_4x4_LUMA
203
204 #define TR_4(dst, src, dstep, sstep, assign, end)                              \
205     do {                                                                       \
206         const int e0 = 64 * src[0 * sstep] + 64 * src[2 * sstep];              \
207         const int e1 = 64 * src[0 * sstep] - 64 * src[2 * sstep];              \
208         const int o0 = 83 * src[1 * sstep] + 36 * src[3 * sstep];              \
209         const int o1 = 36 * src[1 * sstep] - 83 * src[3 * sstep];              \
210                                                                                \
211         assign(dst[0 * dstep], e0 + o0);                                       \
212         assign(dst[1 * dstep], e1 + o1);                                       \
213         assign(dst[2 * dstep], e1 - o1);                                       \
214         assign(dst[3 * dstep], e0 - o0);                                       \
215     } while (0)
216
217 #define TR_8(dst, src, dstep, sstep, assign, end)                              \
218     do {                                                                       \
219         int i, j;                                                              \
220         int e_8[4];                                                            \
221         int o_8[4] = { 0 };                                                    \
222         for (i = 0; i < 4; i++)                                                \
223             for (j = 1; j < end; j += 2)                                       \
224                 o_8[i] += transform[4 * j][i] * src[j * sstep];                \
225         TR_4(e_8, src, 1, 2 * sstep, SET, 4);                                  \
226                                                                                \
227         for (i = 0; i < 4; i++) {                                              \
228             assign(dst[i * dstep], e_8[i] + o_8[i]);                           \
229             assign(dst[(7 - i) * dstep], e_8[i] - o_8[i]);                     \
230         }                                                                      \
231     } while (0)
232
233 #define TR_16(dst, src, dstep, sstep, assign, end)                             \
234     do {                                                                       \
235         int i, j;                                                              \
236         int e_16[8];                                                           \
237         int o_16[8] = { 0 };                                                   \
238         for (i = 0; i < 8; i++)                                                \
239             for (j = 1; j < end; j += 2)                                       \
240                 o_16[i] += transform[2 * j][i] * src[j * sstep];               \
241         TR_8(e_16, src, 1, 2 * sstep, SET, 8);                                 \
242                                                                                \
243         for (i = 0; i < 8; i++) {                                              \
244             assign(dst[i * dstep], e_16[i] + o_16[i]);                         \
245             assign(dst[(15 - i) * dstep], e_16[i] - o_16[i]);                  \
246         }                                                                      \
247     } while (0)
248
249 #define TR_32(dst, src, dstep, sstep, assign, end)                             \
250     do {                                                                       \
251         int i, j;                                                              \
252         int e_32[16];                                                          \
253         int o_32[16] = { 0 };                                                  \
254         for (i = 0; i < 16; i++)                                               \
255             for (j = 1; j < end; j += 2)                                       \
256                 o_32[i] += transform[j][i] * src[j * sstep];                   \
257         TR_16(e_32, src, 1, 2 * sstep, SET, end/2);                            \
258                                                                                \
259         for (i = 0; i < 16; i++) {                                             \
260             assign(dst[i * dstep], e_32[i] + o_32[i]);                         \
261             assign(dst[(31 - i) * dstep], e_32[i] - o_32[i]);                  \
262         }                                                                      \
263     } while (0)
264
265 #define IDCT_VAR4(H)                                                          \
266     int      limit2   = FFMIN(col_limit + 4, H)
267 #define IDCT_VAR8(H)                                                          \
268         int      limit   = FFMIN(col_limit, H);                               \
269         int      limit2   = FFMIN(col_limit + 4, H)
270 #define IDCT_VAR16(H)   IDCT_VAR8(H)
271 #define IDCT_VAR32(H)   IDCT_VAR8(H)
272
273 #define IDCT(H)                                                              \
274 static void FUNC(idct_##H ##x ##H )(                                         \
275                    int16_t *coeffs, int col_limit) {                         \
276     int i;                                                                   \
277     int      shift   = 7;                                                    \
278     int      add     = 1 << (shift - 1);                                     \
279     int16_t *src     = coeffs;                                               \
280     IDCT_VAR ##H(H);                                                         \
281                                                                              \
282     for (i = 0; i < H; i++) {                                                \
283         TR_ ## H(src, src, H, H, SCALE, limit2);                             \
284         if (limit2 < H && i%4 == 0 && !!i)                                   \
285             limit2 -= 4;                                                     \
286         src++;                                                               \
287     }                                                                        \
288                                                                              \
289     shift   = 20 - BIT_DEPTH;                                                \
290     add     = 1 << (shift - 1);                                              \
291     for (i = 0; i < H; i++) {                                                \
292         TR_ ## H(coeffs, coeffs, 1, 1, SCALE, limit);                        \
293         coeffs += H;                                                         \
294     }                                                                        \
295 }
296
297 #define IDCT_DC(H)                                                           \
298 static void FUNC(idct_##H ##x ##H ##_dc)(                                    \
299                    int16_t *coeffs) {                                        \
300     int i, j;                                                                \
301     int      shift   = 14 - BIT_DEPTH;                                       \
302     int      add     = 1 << (shift - 1);                                     \
303     int      coeff   = (((coeffs[0] + 1) >> 1) + add) >> shift;              \
304                                                                              \
305     for (j = 0; j < H; j++) {                                                \
306         for (i = 0; i < H; i++) {                                            \
307             coeffs[i+j*H] = coeff;                                           \
308         }                                                                    \
309     }                                                                        \
310 }
311
312 IDCT( 4)
313 IDCT( 8)
314 IDCT(16)
315 IDCT(32)
316
317 IDCT_DC( 4)
318 IDCT_DC( 8)
319 IDCT_DC(16)
320 IDCT_DC(32)
321
322 #undef TR_4
323 #undef TR_8
324 #undef TR_16
325 #undef TR_32
326
327 #undef SET
328 #undef SCALE
329 #undef ADD_AND_SCALE
330
331 static void FUNC(sao_band_filter_0)(uint8_t *_dst, uint8_t *_src,
332                                   ptrdiff_t stride_dst, ptrdiff_t stride_src, SAOParams *sao,
333                                   int *borders, int width, int height,
334                                   int c_idx)
335 {
336     pixel *dst = (pixel *)_dst;
337     pixel *src = (pixel *)_src;
338     int offset_table[32] = { 0 };
339     int k, y, x;
340     int shift  = BIT_DEPTH - 5;
341     int16_t *sao_offset_val = sao->offset_val[c_idx];
342     int sao_left_class  = sao->band_position[c_idx];
343
344     stride_dst /= sizeof(pixel);
345     stride_src /= sizeof(pixel);
346
347     for (k = 0; k < 4; k++)
348         offset_table[(k + sao_left_class) & 31] = sao_offset_val[k + 1];
349     for (y = 0; y < height; y++) {
350         for (x = 0; x < width; x++)
351             dst[x] = av_clip_pixel(src[x] + offset_table[src[x] >> shift]);
352         dst += stride_dst;
353         src += stride_src;
354     }
355 }
356
357 #define CMP(a, b) ((a) > (b) ? 1 : ((a) == (b) ? 0 : -1))
358
359 static void FUNC(sao_edge_filter)(uint8_t *_dst, uint8_t *_src,
360                                   ptrdiff_t stride_dst, ptrdiff_t stride_src, SAOParams *sao,
361                                   int width, int height,
362                                   int c_idx, int init_x, int init_y) {
363
364     static const uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
365     static const int8_t pos[4][2][2] = {
366         { { -1,  0 }, {  1, 0 } }, // horizontal
367         { {  0, -1 }, {  0, 1 } }, // vertical
368         { { -1, -1 }, {  1, 1 } }, // 45 degree
369         { {  1, -1 }, { -1, 1 } }, // 135 degree
370     };
371     int16_t *sao_offset_val = sao->offset_val[c_idx];
372     int sao_eo_class    = sao->eo_class[c_idx];
373     pixel *dst = (pixel *)_dst;
374     pixel *src = (pixel *)_src;
375
376     int y_stride_src = init_y * stride_src;
377     int y_stride_dst = init_y * stride_dst;
378     int pos_0_0  = pos[sao_eo_class][0][0];
379     int pos_0_1  = pos[sao_eo_class][0][1];
380     int pos_1_0  = pos[sao_eo_class][1][0];
381     int pos_1_1  = pos[sao_eo_class][1][1];
382     int x, y;
383
384     int y_stride_0_1 = (init_y + pos_0_1) * stride_src;
385     int y_stride_1_1 = (init_y + pos_1_1) * stride_src;
386     for (y = init_y; y < height; y++) {
387         for (x = init_x; x < width; x++) {
388             int diff0             = CMP(src[x + y_stride_src], src[x + pos_0_0 + y_stride_0_1]);
389             int diff1             = CMP(src[x + y_stride_src], src[x + pos_1_0 + y_stride_1_1]);
390             int offset_val        = edge_idx[2 + diff0 + diff1];
391             dst[x + y_stride_dst] = av_clip_pixel(src[x + y_stride_src] + sao_offset_val[offset_val]);
392         }
393         y_stride_src += stride_src;
394         y_stride_dst += stride_dst;
395         y_stride_0_1 += stride_src;
396         y_stride_1_1 += stride_src;
397     }
398 }
399
400 static void FUNC(sao_edge_filter_0)(uint8_t *_dst, uint8_t *_src,
401                                     ptrdiff_t stride_dst, ptrdiff_t stride_src, SAOParams *sao,
402                                     int *borders, int _width, int _height,
403                                     int c_idx, uint8_t *vert_edge,
404                                     uint8_t *horiz_edge, uint8_t *diag_edge)
405 {
406     int x, y;
407     pixel *dst = (pixel *)_dst;
408     pixel *src = (pixel *)_src;
409     int16_t *sao_offset_val = sao->offset_val[c_idx];
410     int sao_eo_class    = sao->eo_class[c_idx];
411     int init_x = 0, init_y = 0, width = _width, height = _height;
412
413     stride_dst /= sizeof(pixel);
414     stride_src /= sizeof(pixel);
415
416     if (sao_eo_class != SAO_EO_VERT) {
417         if (borders[0]) {
418             int offset_val = sao_offset_val[0];
419             for (y = 0; y < height; y++) {
420                 dst[y * stride_dst] = av_clip_pixel(src[y * stride_src] + offset_val);
421             }
422             init_x = 1;
423         }
424         if (borders[2]) {
425             int offset_val = sao_offset_val[0];
426             int offset     = width - 1;
427             for (x = 0; x < height; x++) {
428                 dst[x * stride_dst + offset] = av_clip_pixel(src[x * stride_src + offset] + offset_val);
429             }
430             width--;
431         }
432     }
433     if (sao_eo_class != SAO_EO_HORIZ) {
434         if (borders[1]) {
435             int offset_val = sao_offset_val[0];
436             for (x = init_x; x < width; x++)
437                 dst[x] = av_clip_pixel(src[x] + offset_val);
438             init_y = 1;
439         }
440         if (borders[3]) {
441             int offset_val   = sao_offset_val[0];
442             int y_stride_dst = stride_dst * (height - 1);
443             int y_stride_src = stride_src * (height - 1);
444             for (x = init_x; x < width; x++)
445                 dst[x + y_stride_dst] = av_clip_pixel(src[x + y_stride_src] + offset_val);
446             height--;
447         }
448     }
449
450     FUNC(sao_edge_filter)((uint8_t *)dst, (uint8_t *)src, stride_dst, stride_src, sao, width, height, c_idx, init_x, init_y);
451 }
452
453 static void FUNC(sao_edge_filter_1)(uint8_t *_dst, uint8_t *_src,
454                                     ptrdiff_t stride_dst, ptrdiff_t stride_src, SAOParams *sao,
455                                     int *borders, int _width, int _height,
456                                     int c_idx, uint8_t *vert_edge,
457                                     uint8_t *horiz_edge, uint8_t *diag_edge)
458 {
459     int x, y;
460     pixel *dst = (pixel *)_dst;
461     pixel *src = (pixel *)_src;
462     int16_t *sao_offset_val = sao->offset_val[c_idx];
463     int sao_eo_class    = sao->eo_class[c_idx];
464     int init_x = 0, init_y = 0, width = _width, height = _height;
465
466     stride_dst /= sizeof(pixel);
467     stride_src /= sizeof(pixel);
468
469     if (sao_eo_class != SAO_EO_VERT) {
470         if (borders[0]) {
471             int offset_val = sao_offset_val[0];
472             for (y = 0; y < height; y++) {
473                 dst[y * stride_dst] = av_clip_pixel(src[y * stride_src] + offset_val);
474             }
475             init_x = 1;
476         }
477         if (borders[2]) {
478             int offset_val = sao_offset_val[0];
479             int offset     = width - 1;
480             for (x = 0; x < height; x++) {
481                 dst[x * stride_dst + offset] = av_clip_pixel(src[x * stride_src + offset] + offset_val);
482             }
483             width--;
484         }
485     }
486     if (sao_eo_class != SAO_EO_HORIZ) {
487         if (borders[1]) {
488             int offset_val = sao_offset_val[0];
489             for (x = init_x; x < width; x++)
490                 dst[x] = av_clip_pixel(src[x] + offset_val);
491             init_y = 1;
492         }
493         if (borders[3]) {
494             int offset_val   = sao_offset_val[0];
495             int y_stride_dst = stride_dst * (height - 1);
496             int y_stride_src = stride_src * (height - 1);
497             for (x = init_x; x < width; x++)
498                 dst[x + y_stride_dst] = av_clip_pixel(src[x + y_stride_src] + offset_val);
499             height--;
500         }
501     }
502
503     FUNC(sao_edge_filter)((uint8_t *)dst, (uint8_t *)src, stride_dst, stride_src, sao, width, height, c_idx, init_x, init_y);
504
505     {
506         int save_upper_left  = !diag_edge[0] && sao_eo_class == SAO_EO_135D && !borders[0] && !borders[1];
507         int save_upper_right = !diag_edge[1] && sao_eo_class == SAO_EO_45D  && !borders[1] && !borders[2];
508         int save_lower_right = !diag_edge[2] && sao_eo_class == SAO_EO_135D && !borders[2] && !borders[3];
509         int save_lower_left  = !diag_edge[3] && sao_eo_class == SAO_EO_45D  && !borders[0] && !borders[3];
510
511         // Restore pixels that can't be modified
512         if(vert_edge[0] && sao_eo_class != SAO_EO_VERT) {
513             for(y = init_y+save_upper_left; y< height-save_lower_left; y++)
514                 dst[y*stride_dst] = src[y*stride_src];
515         }
516         if(vert_edge[1] && sao_eo_class != SAO_EO_VERT) {
517             for(y = init_y+save_upper_right; y< height-save_lower_right; y++)
518                 dst[y*stride_dst+width-1] = src[y*stride_src+width-1];
519         }
520
521         if(horiz_edge[0] && sao_eo_class != SAO_EO_HORIZ) {
522             for(x = init_x+save_upper_left; x < width-save_upper_right; x++)
523                 dst[x] = src[x];
524         }
525         if(horiz_edge[1] && sao_eo_class != SAO_EO_HORIZ) {
526             for(x = init_x+save_lower_left; x < width-save_lower_right; x++)
527                 dst[(height-1)*stride_dst+x] = src[(height-1)*stride_src+x];
528         }
529         if(diag_edge[0] && sao_eo_class == SAO_EO_135D)
530             dst[0] = src[0];
531         if(diag_edge[1] && sao_eo_class == SAO_EO_45D)
532             dst[width-1] = src[width-1];
533         if(diag_edge[2] && sao_eo_class == SAO_EO_135D)
534             dst[stride_dst*(height-1)+width-1] = src[stride_src*(height-1)+width-1];
535         if(diag_edge[3] && sao_eo_class == SAO_EO_45D)
536             dst[stride_dst*(height-1)] = src[stride_src*(height-1)];
537
538     }
539 }
540
541 #undef CMP
542
543 ////////////////////////////////////////////////////////////////////////////////
544 //
545 ////////////////////////////////////////////////////////////////////////////////
546 static void FUNC(put_hevc_pel_pixels)(int16_t *dst, ptrdiff_t dststride,
547                                       uint8_t *_src, ptrdiff_t _srcstride,
548                                       int height, intptr_t mx, intptr_t my, int width)
549 {
550     int x, y;
551     pixel *src          = (pixel *)_src;
552     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
553
554     for (y = 0; y < height; y++) {
555         for (x = 0; x < width; x++)
556             dst[x] = src[x] << (14 - BIT_DEPTH);
557         src += srcstride;
558         dst += dststride;
559     }
560 }
561
562 static void FUNC(put_hevc_pel_uni_pixels)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
563                                           int height, intptr_t mx, intptr_t my, int width)
564 {
565     int y;
566     pixel *src          = (pixel *)_src;
567     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
568     pixel *dst          = (pixel *)_dst;
569     ptrdiff_t dststride = _dststride / sizeof(pixel);
570
571     for (y = 0; y < height; y++) {
572         memcpy(dst, src, width * sizeof(pixel));
573         src += srcstride;
574         dst += dststride;
575     }
576 }
577
578 static void FUNC(put_hevc_pel_bi_pixels)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
579                                          int16_t *src2, ptrdiff_t src2stride,
580                                          int height, intptr_t mx, intptr_t my, int width)
581 {
582     int x, y;
583     pixel *src          = (pixel *)_src;
584     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
585     pixel *dst          = (pixel *)_dst;
586     ptrdiff_t dststride = _dststride / sizeof(pixel);
587
588     int shift = 14  + 1 - BIT_DEPTH;
589 #if BIT_DEPTH < 14
590     int offset = 1 << (shift - 1);
591 #else
592     int offset = 0;
593 #endif
594
595     for (y = 0; y < height; y++) {
596         for (x = 0; x < width; x++)
597             dst[x] = av_clip_pixel(((src[x] << (14 - BIT_DEPTH)) + src2[x] + offset) >> shift);
598         src  += srcstride;
599         dst  += dststride;
600         src2 += src2stride;
601     }
602 }
603
604 static void FUNC(put_hevc_pel_uni_w_pixels)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
605                                             int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width)
606 {
607     int x, y;
608     pixel *src          = (pixel *)_src;
609     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
610     pixel *dst          = (pixel *)_dst;
611     ptrdiff_t dststride = _dststride / sizeof(pixel);
612     int shift = denom + 14 - BIT_DEPTH;
613 #if BIT_DEPTH < 14
614     int offset = 1 << (shift - 1);
615 #else
616     int offset = 0;
617 #endif
618
619     ox     = ox * (1 << (BIT_DEPTH - 8));
620     for (y = 0; y < height; y++) {
621         for (x = 0; x < width; x++)
622             dst[x] = av_clip_pixel((((src[x] << (14 - BIT_DEPTH)) * wx + offset) >> shift) + ox);
623         src += srcstride;
624         dst += dststride;
625     }
626 }
627
628 static void FUNC(put_hevc_pel_bi_w_pixels)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
629                                            int16_t *src2, ptrdiff_t src2stride,
630                                            int height, int denom, int wx0, int wx1,
631                                            int ox0, int ox1, intptr_t mx, intptr_t my, int width)
632 {
633     int x, y;
634     pixel *src          = (pixel *)_src;
635     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
636     pixel *dst          = (pixel *)_dst;
637     ptrdiff_t dststride = _dststride / sizeof(pixel);
638
639     int shift = 14  + 1 - BIT_DEPTH;
640     int log2Wd = denom + shift - 1;
641
642     ox0     = ox0 * (1 << (BIT_DEPTH - 8));
643     ox1     = ox1 * (1 << (BIT_DEPTH - 8));
644     for (y = 0; y < height; y++) {
645         for (x = 0; x < width; x++) {
646             dst[x] = av_clip_pixel(( (src[x] << (14 - BIT_DEPTH)) * wx1 + src2[x] * wx0 + ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1));
647         }
648         src  += srcstride;
649         dst  += dststride;
650         src2 += src2stride;
651     }
652 }
653
654 ////////////////////////////////////////////////////////////////////////////////
655 //
656 ////////////////////////////////////////////////////////////////////////////////
657 #define QPEL_FILTER(src, stride)                                               \
658     (filter[0] * src[x - 3 * stride] +                                         \
659      filter[1] * src[x - 2 * stride] +                                         \
660      filter[2] * src[x -     stride] +                                         \
661      filter[3] * src[x             ] +                                         \
662      filter[4] * src[x +     stride] +                                         \
663      filter[5] * src[x + 2 * stride] +                                         \
664      filter[6] * src[x + 3 * stride] +                                         \
665      filter[7] * src[x + 4 * stride])
666
667 static void FUNC(put_hevc_qpel_h)(int16_t *dst,  ptrdiff_t dststride,
668                                   uint8_t *_src, ptrdiff_t _srcstride,
669                                   int height, intptr_t mx, intptr_t my, int width)
670 {
671     int x, y;
672     pixel        *src       = (pixel*)_src;
673     ptrdiff_t     srcstride = _srcstride / sizeof(pixel);
674     const int8_t *filter    = ff_hevc_qpel_filters[mx - 1];
675     for (y = 0; y < height; y++) {
676         for (x = 0; x < width; x++)
677             dst[x] = QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
678         src += srcstride;
679         dst += dststride;
680     }
681 }
682
683 static void FUNC(put_hevc_qpel_v)(int16_t *dst,  ptrdiff_t dststride,
684                                   uint8_t *_src, ptrdiff_t _srcstride,
685                                   int height, intptr_t mx, intptr_t my, int width)
686 {
687     int x, y;
688     pixel        *src       = (pixel*)_src;
689     ptrdiff_t     srcstride = _srcstride / sizeof(pixel);
690     const int8_t *filter    = ff_hevc_qpel_filters[my - 1];
691     for (y = 0; y < height; y++)  {
692         for (x = 0; x < width; x++)
693             dst[x] = QPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8);
694         src += srcstride;
695         dst += dststride;
696     }
697 }
698
699 static void FUNC(put_hevc_qpel_hv)(int16_t *dst,
700                                    ptrdiff_t dststride,
701                                    uint8_t *_src,
702                                    ptrdiff_t _srcstride,
703                                    int height, intptr_t mx,
704                                    intptr_t my, int width)
705 {
706     int x, y;
707     const int8_t *filter;
708     pixel *src = (pixel*)_src;
709     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
710     int16_t tmp_array[(MAX_PB_SIZE + QPEL_EXTRA) * MAX_PB_SIZE];
711     int16_t *tmp = tmp_array;
712
713     src   -= QPEL_EXTRA_BEFORE * srcstride;
714     filter = ff_hevc_qpel_filters[mx - 1];
715     for (y = 0; y < height + QPEL_EXTRA; y++) {
716         for (x = 0; x < width; x++)
717             tmp[x] = QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
718         src += srcstride;
719         tmp += MAX_PB_SIZE;
720     }
721
722     tmp    = tmp_array + QPEL_EXTRA_BEFORE * MAX_PB_SIZE;
723     filter = ff_hevc_qpel_filters[my - 1];
724     for (y = 0; y < height; y++) {
725         for (x = 0; x < width; x++)
726             dst[x] = QPEL_FILTER(tmp, MAX_PB_SIZE) >> 6;
727         tmp += MAX_PB_SIZE;
728         dst += dststride;
729     }
730 }
731
732 static void FUNC(put_hevc_qpel_uni_h)(uint8_t *_dst,  ptrdiff_t _dststride,
733                                       uint8_t *_src, ptrdiff_t _srcstride,
734                                       int height, intptr_t mx, intptr_t my, int width)
735 {
736     int x, y;
737     pixel        *src       = (pixel*)_src;
738     ptrdiff_t     srcstride = _srcstride / sizeof(pixel);
739     pixel *dst          = (pixel *)_dst;
740     ptrdiff_t dststride = _dststride / sizeof(pixel);
741     const int8_t *filter    = ff_hevc_qpel_filters[mx - 1];
742     int shift = 14 - BIT_DEPTH;
743
744 #if BIT_DEPTH < 14
745     int offset = 1 << (shift - 1);
746 #else
747     int offset = 0;
748 #endif
749
750     for (y = 0; y < height; y++) {
751         for (x = 0; x < width; x++)
752             dst[x] = av_clip_pixel(((QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8)) + offset) >> shift);
753         src += srcstride;
754         dst += dststride;
755     }
756 }
757
758 static void FUNC(put_hevc_qpel_bi_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
759                                      int16_t *src2, ptrdiff_t src2stride,
760                                      int height, intptr_t mx, intptr_t my, int width)
761 {
762     int x, y;
763     pixel        *src       = (pixel*)_src;
764     ptrdiff_t     srcstride = _srcstride / sizeof(pixel);
765     pixel *dst          = (pixel *)_dst;
766     ptrdiff_t dststride = _dststride / sizeof(pixel);
767
768     const int8_t *filter    = ff_hevc_qpel_filters[mx - 1];
769
770     int shift = 14  + 1 - BIT_DEPTH;
771 #if BIT_DEPTH < 14
772     int offset = 1 << (shift - 1);
773 #else
774     int offset = 0;
775 #endif
776
777     for (y = 0; y < height; y++) {
778         for (x = 0; x < width; x++)
779             dst[x] = av_clip_pixel(((QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8)) + src2[x] + offset) >> shift);
780         src  += srcstride;
781         dst  += dststride;
782         src2 += src2stride;
783     }
784 }
785
786 static void FUNC(put_hevc_qpel_uni_v)(uint8_t *_dst,  ptrdiff_t _dststride,
787                                      uint8_t *_src, ptrdiff_t _srcstride,
788                                      int height, intptr_t mx, intptr_t my, int width)
789 {
790     int x, y;
791     pixel        *src       = (pixel*)_src;
792     ptrdiff_t     srcstride = _srcstride / sizeof(pixel);
793     pixel *dst          = (pixel *)_dst;
794     ptrdiff_t dststride = _dststride / sizeof(pixel);
795     const int8_t *filter    = ff_hevc_qpel_filters[my - 1];
796     int shift = 14 - BIT_DEPTH;
797
798 #if BIT_DEPTH < 14
799     int offset = 1 << (shift - 1);
800 #else
801     int offset = 0;
802 #endif
803
804     for (y = 0; y < height; y++) {
805         for (x = 0; x < width; x++)
806             dst[x] = av_clip_pixel(((QPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8)) + offset) >> shift);
807         src += srcstride;
808         dst += dststride;
809     }
810 }
811
812
813 static void FUNC(put_hevc_qpel_bi_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
814                                      int16_t *src2, ptrdiff_t src2stride,
815                                      int height, intptr_t mx, intptr_t my, int width)
816 {
817     int x, y;
818     pixel        *src       = (pixel*)_src;
819     ptrdiff_t     srcstride = _srcstride / sizeof(pixel);
820     pixel *dst          = (pixel *)_dst;
821     ptrdiff_t dststride = _dststride / sizeof(pixel);
822
823     const int8_t *filter    = ff_hevc_qpel_filters[my - 1];
824
825     int shift = 14 + 1 - BIT_DEPTH;
826 #if BIT_DEPTH < 14
827     int offset = 1 << (shift - 1);
828 #else
829     int offset = 0;
830 #endif
831
832     for (y = 0; y < height; y++) {
833         for (x = 0; x < width; x++)
834             dst[x] = av_clip_pixel(((QPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8)) + src2[x] + offset) >> shift);
835         src  += srcstride;
836         dst  += dststride;
837         src2 += src2stride;
838     }
839 }
840
841 static void FUNC(put_hevc_qpel_uni_hv)(uint8_t *_dst,  ptrdiff_t _dststride,
842                                        uint8_t *_src, ptrdiff_t _srcstride,
843                                        int height, intptr_t mx, intptr_t my, int width)
844 {
845     int x, y;
846     const int8_t *filter;
847     pixel *src = (pixel*)_src;
848     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
849     pixel *dst          = (pixel *)_dst;
850     ptrdiff_t dststride = _dststride / sizeof(pixel);
851     int16_t tmp_array[(MAX_PB_SIZE + QPEL_EXTRA) * MAX_PB_SIZE];
852     int16_t *tmp = tmp_array;
853     int shift =  14 - BIT_DEPTH;
854
855 #if BIT_DEPTH < 14
856     int offset = 1 << (shift - 1);
857 #else
858     int offset = 0;
859 #endif
860
861     src   -= QPEL_EXTRA_BEFORE * srcstride;
862     filter = ff_hevc_qpel_filters[mx - 1];
863     for (y = 0; y < height + QPEL_EXTRA; y++) {
864         for (x = 0; x < width; x++)
865             tmp[x] = QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
866         src += srcstride;
867         tmp += MAX_PB_SIZE;
868     }
869
870     tmp    = tmp_array + QPEL_EXTRA_BEFORE * MAX_PB_SIZE;
871     filter = ff_hevc_qpel_filters[my - 1];
872
873     for (y = 0; y < height; y++) {
874         for (x = 0; x < width; x++)
875             dst[x] = av_clip_pixel(((QPEL_FILTER(tmp, MAX_PB_SIZE) >> 6) + offset) >> shift);
876         tmp += MAX_PB_SIZE;
877         dst += dststride;
878     }
879 }
880
881 static void FUNC(put_hevc_qpel_bi_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
882                                       int16_t *src2, ptrdiff_t src2stride,
883                                       int height, intptr_t mx, intptr_t my, int width)
884 {
885     int x, y;
886     const int8_t *filter;
887     pixel *src = (pixel*)_src;
888     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
889     pixel *dst          = (pixel *)_dst;
890     ptrdiff_t dststride = _dststride / sizeof(pixel);
891     int16_t tmp_array[(MAX_PB_SIZE + QPEL_EXTRA) * MAX_PB_SIZE];
892     int16_t *tmp = tmp_array;
893     int shift = 14 + 1 - BIT_DEPTH;
894 #if BIT_DEPTH < 14
895     int offset = 1 << (shift - 1);
896 #else
897     int offset = 0;
898 #endif
899
900     src   -= QPEL_EXTRA_BEFORE * srcstride;
901     filter = ff_hevc_qpel_filters[mx - 1];
902     for (y = 0; y < height + QPEL_EXTRA; y++) {
903         for (x = 0; x < width; x++)
904             tmp[x] = QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
905         src += srcstride;
906         tmp += MAX_PB_SIZE;
907     }
908
909     tmp    = tmp_array + QPEL_EXTRA_BEFORE * MAX_PB_SIZE;
910     filter = ff_hevc_qpel_filters[my - 1];
911
912     for (y = 0; y < height; y++) {
913         for (x = 0; x < width; x++)
914             dst[x] = av_clip_pixel(((QPEL_FILTER(tmp, MAX_PB_SIZE) >> 6) + src2[x] + offset) >> shift);
915         tmp  += MAX_PB_SIZE;
916         dst  += dststride;
917         src2 += src2stride;
918     }
919 }
920
921 static void FUNC(put_hevc_qpel_uni_w_h)(uint8_t *_dst,  ptrdiff_t _dststride,
922                                         uint8_t *_src, ptrdiff_t _srcstride,
923                                         int height, int denom, int wx, int ox,
924                                         intptr_t mx, intptr_t my, int width)
925 {
926     int x, y;
927     pixel        *src       = (pixel*)_src;
928     ptrdiff_t     srcstride = _srcstride / sizeof(pixel);
929     pixel *dst          = (pixel *)_dst;
930     ptrdiff_t dststride = _dststride / sizeof(pixel);
931     const int8_t *filter    = ff_hevc_qpel_filters[mx - 1];
932     int shift = denom + 14 - BIT_DEPTH;
933 #if BIT_DEPTH < 14
934     int offset = 1 << (shift - 1);
935 #else
936     int offset = 0;
937 #endif
938
939     ox = ox * (1 << (BIT_DEPTH - 8));
940     for (y = 0; y < height; y++) {
941         for (x = 0; x < width; x++)
942             dst[x] = av_clip_pixel((((QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8)) * wx + offset) >> shift) + ox);
943         src += srcstride;
944         dst += dststride;
945     }
946 }
947
948 static void FUNC(put_hevc_qpel_bi_w_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
949                                        int16_t *src2, ptrdiff_t src2stride,
950                                        int height, int denom, int wx0, int wx1,
951                                        int ox0, int ox1, intptr_t mx, intptr_t my, int width)
952 {
953     int x, y;
954     pixel        *src       = (pixel*)_src;
955     ptrdiff_t     srcstride = _srcstride / sizeof(pixel);
956     pixel *dst          = (pixel *)_dst;
957     ptrdiff_t dststride = _dststride / sizeof(pixel);
958
959     const int8_t *filter    = ff_hevc_qpel_filters[mx - 1];
960
961     int shift = 14  + 1 - BIT_DEPTH;
962     int log2Wd = denom + shift - 1;
963
964     ox0     = ox0 * (1 << (BIT_DEPTH - 8));
965     ox1     = ox1 * (1 << (BIT_DEPTH - 8));
966     for (y = 0; y < height; y++) {
967         for (x = 0; x < width; x++)
968             dst[x] = av_clip_pixel(((QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8)) * wx1 + src2[x] * wx0 +
969                                     ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1));
970         src  += srcstride;
971         dst  += dststride;
972         src2 += src2stride;
973     }
974 }
975
976 static void FUNC(put_hevc_qpel_uni_w_v)(uint8_t *_dst,  ptrdiff_t _dststride,
977                                         uint8_t *_src, ptrdiff_t _srcstride,
978                                         int height, int denom, int wx, int ox,
979                                         intptr_t mx, intptr_t my, int width)
980 {
981     int x, y;
982     pixel        *src       = (pixel*)_src;
983     ptrdiff_t     srcstride = _srcstride / sizeof(pixel);
984     pixel *dst          = (pixel *)_dst;
985     ptrdiff_t dststride = _dststride / sizeof(pixel);
986     const int8_t *filter    = ff_hevc_qpel_filters[my - 1];
987     int shift = denom + 14 - BIT_DEPTH;
988 #if BIT_DEPTH < 14
989     int offset = 1 << (shift - 1);
990 #else
991     int offset = 0;
992 #endif
993
994     ox = ox * (1 << (BIT_DEPTH - 8));
995     for (y = 0; y < height; y++) {
996         for (x = 0; x < width; x++)
997             dst[x] = av_clip_pixel((((QPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8)) * wx + offset) >> shift) + ox);
998         src += srcstride;
999         dst += dststride;
1000     }
1001 }
1002
1003 static void FUNC(put_hevc_qpel_bi_w_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1004                                        int16_t *src2, ptrdiff_t src2stride,
1005                                        int height, int denom, int wx0, int wx1,
1006                                        int ox0, int ox1, intptr_t mx, intptr_t my, int width)
1007 {
1008     int x, y;
1009     pixel        *src       = (pixel*)_src;
1010     ptrdiff_t     srcstride = _srcstride / sizeof(pixel);
1011     pixel *dst          = (pixel *)_dst;
1012     ptrdiff_t dststride = _dststride / sizeof(pixel);
1013
1014     const int8_t *filter    = ff_hevc_qpel_filters[my - 1];
1015
1016     int shift = 14 + 1 - BIT_DEPTH;
1017     int log2Wd = denom + shift - 1;
1018
1019     ox0     = ox0 * (1 << (BIT_DEPTH - 8));
1020     ox1     = ox1 * (1 << (BIT_DEPTH - 8));
1021     for (y = 0; y < height; y++) {
1022         for (x = 0; x < width; x++)
1023             dst[x] = av_clip_pixel(((QPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8)) * wx1 + src2[x] * wx0 +
1024                                     ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1));
1025         src  += srcstride;
1026         dst  += dststride;
1027         src2 += src2stride;
1028     }
1029 }
1030
1031 static void FUNC(put_hevc_qpel_uni_w_hv)(uint8_t *_dst,  ptrdiff_t _dststride,
1032                                          uint8_t *_src, ptrdiff_t _srcstride,
1033                                          int height, int denom, int wx, int ox,
1034                                          intptr_t mx, intptr_t my, int width)
1035 {
1036     int x, y;
1037     const int8_t *filter;
1038     pixel *src = (pixel*)_src;
1039     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
1040     pixel *dst          = (pixel *)_dst;
1041     ptrdiff_t dststride = _dststride / sizeof(pixel);
1042     int16_t tmp_array[(MAX_PB_SIZE + QPEL_EXTRA) * MAX_PB_SIZE];
1043     int16_t *tmp = tmp_array;
1044     int shift = denom + 14 - BIT_DEPTH;
1045 #if BIT_DEPTH < 14
1046     int offset = 1 << (shift - 1);
1047 #else
1048     int offset = 0;
1049 #endif
1050
1051     src   -= QPEL_EXTRA_BEFORE * srcstride;
1052     filter = ff_hevc_qpel_filters[mx - 1];
1053     for (y = 0; y < height + QPEL_EXTRA; y++) {
1054         for (x = 0; x < width; x++)
1055             tmp[x] = QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
1056         src += srcstride;
1057         tmp += MAX_PB_SIZE;
1058     }
1059
1060     tmp    = tmp_array + QPEL_EXTRA_BEFORE * MAX_PB_SIZE;
1061     filter = ff_hevc_qpel_filters[my - 1];
1062
1063     ox = ox * (1 << (BIT_DEPTH - 8));
1064     for (y = 0; y < height; y++) {
1065         for (x = 0; x < width; x++)
1066             dst[x] = av_clip_pixel((((QPEL_FILTER(tmp, MAX_PB_SIZE) >> 6) * wx + offset) >> shift) + ox);
1067         tmp += MAX_PB_SIZE;
1068         dst += dststride;
1069     }
1070 }
1071
1072 static void FUNC(put_hevc_qpel_bi_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1073                                         int16_t *src2, ptrdiff_t src2stride,
1074                                         int height, int denom, int wx0, int wx1,
1075                                         int ox0, int ox1, intptr_t mx, intptr_t my, int width)
1076 {
1077     int x, y;
1078     const int8_t *filter;
1079     pixel *src = (pixel*)_src;
1080     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
1081     pixel *dst          = (pixel *)_dst;
1082     ptrdiff_t dststride = _dststride / sizeof(pixel);
1083     int16_t tmp_array[(MAX_PB_SIZE + QPEL_EXTRA) * MAX_PB_SIZE];
1084     int16_t *tmp = tmp_array;
1085     int shift = 14 + 1 - BIT_DEPTH;
1086     int log2Wd = denom + shift - 1;
1087
1088     src   -= QPEL_EXTRA_BEFORE * srcstride;
1089     filter = ff_hevc_qpel_filters[mx - 1];
1090     for (y = 0; y < height + QPEL_EXTRA; y++) {
1091         for (x = 0; x < width; x++)
1092             tmp[x] = QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
1093         src += srcstride;
1094         tmp += MAX_PB_SIZE;
1095     }
1096
1097     tmp    = tmp_array + QPEL_EXTRA_BEFORE * MAX_PB_SIZE;
1098     filter = ff_hevc_qpel_filters[my - 1];
1099
1100     ox0     = ox0 * (1 << (BIT_DEPTH - 8));
1101     ox1     = ox1 * (1 << (BIT_DEPTH - 8));
1102     for (y = 0; y < height; y++) {
1103         for (x = 0; x < width; x++)
1104             dst[x] = av_clip_pixel(((QPEL_FILTER(tmp, MAX_PB_SIZE) >> 6) * wx1 + src2[x] * wx0 +
1105                                     ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1));
1106         tmp  += MAX_PB_SIZE;
1107         dst  += dststride;
1108         src2 += src2stride;
1109     }
1110 }
1111
1112 ////////////////////////////////////////////////////////////////////////////////
1113 //
1114 ////////////////////////////////////////////////////////////////////////////////
1115 #define EPEL_FILTER(src, stride)                                               \
1116     (filter[0] * src[x - stride] +                                             \
1117      filter[1] * src[x]          +                                             \
1118      filter[2] * src[x + stride] +                                             \
1119      filter[3] * src[x + 2 * stride])
1120
1121 static void FUNC(put_hevc_epel_h)(int16_t *dst, ptrdiff_t dststride,
1122                                   uint8_t *_src, ptrdiff_t _srcstride,
1123                                   int height, intptr_t mx, intptr_t my, int width)
1124 {
1125     int x, y;
1126     pixel *src = (pixel *)_src;
1127     ptrdiff_t srcstride  = _srcstride / sizeof(pixel);
1128     const int8_t *filter = ff_hevc_epel_filters[mx - 1];
1129     for (y = 0; y < height; y++) {
1130         for (x = 0; x < width; x++)
1131             dst[x] = EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
1132         src += srcstride;
1133         dst += dststride;
1134     }
1135 }
1136
1137 static void FUNC(put_hevc_epel_v)(int16_t *dst, ptrdiff_t dststride,
1138                                   uint8_t *_src, ptrdiff_t _srcstride,
1139                                   int height, intptr_t mx, intptr_t my, int width)
1140 {
1141     int x, y;
1142     pixel *src = (pixel *)_src;
1143     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
1144     const int8_t *filter = ff_hevc_epel_filters[my - 1];
1145
1146     for (y = 0; y < height; y++) {
1147         for (x = 0; x < width; x++)
1148             dst[x] = EPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8);
1149         src += srcstride;
1150         dst += dststride;
1151     }
1152 }
1153
1154 static void FUNC(put_hevc_epel_hv)(int16_t *dst, ptrdiff_t dststride,
1155                                    uint8_t *_src, ptrdiff_t _srcstride,
1156                                    int height, intptr_t mx, intptr_t my, int width)
1157 {
1158     int x, y;
1159     pixel *src = (pixel *)_src;
1160     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
1161     const int8_t *filter = ff_hevc_epel_filters[mx - 1];
1162     int16_t tmp_array[(MAX_PB_SIZE + EPEL_EXTRA) * MAX_PB_SIZE];
1163     int16_t *tmp = tmp_array;
1164
1165     src -= EPEL_EXTRA_BEFORE * srcstride;
1166
1167     for (y = 0; y < height + EPEL_EXTRA; y++) {
1168         for (x = 0; x < width; x++)
1169             tmp[x] = EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
1170         src += srcstride;
1171         tmp += MAX_PB_SIZE;
1172     }
1173
1174     tmp      = tmp_array + EPEL_EXTRA_BEFORE * MAX_PB_SIZE;
1175     filter = ff_hevc_epel_filters[my - 1];
1176
1177     for (y = 0; y < height; y++) {
1178         for (x = 0; x < width; x++)
1179             dst[x] = EPEL_FILTER(tmp, MAX_PB_SIZE) >> 6;
1180         tmp += MAX_PB_SIZE;
1181         dst += dststride;
1182     }
1183 }
1184
1185 static void FUNC(put_hevc_epel_uni_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1186                                       int height, intptr_t mx, intptr_t my, int width)
1187 {
1188     int x, y;
1189     pixel *src = (pixel *)_src;
1190     ptrdiff_t srcstride  = _srcstride / sizeof(pixel);
1191     pixel *dst          = (pixel *)_dst;
1192     ptrdiff_t dststride = _dststride / sizeof(pixel);
1193     const int8_t *filter = ff_hevc_epel_filters[mx - 1];
1194     int shift = 14 - BIT_DEPTH;
1195 #if BIT_DEPTH < 14
1196     int offset = 1 << (shift - 1);
1197 #else
1198     int offset = 0;
1199 #endif
1200
1201     for (y = 0; y < height; y++) {
1202         for (x = 0; x < width; x++)
1203             dst[x] = av_clip_pixel(((EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8)) + offset) >> shift);
1204         src += srcstride;
1205         dst += dststride;
1206     }
1207 }
1208
1209 static void FUNC(put_hevc_epel_bi_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1210                                      int16_t *src2, ptrdiff_t src2stride,
1211                                      int height, intptr_t mx, intptr_t my, int width)
1212 {
1213     int x, y;
1214     pixel *src = (pixel *)_src;
1215     ptrdiff_t srcstride  = _srcstride / sizeof(pixel);
1216     pixel *dst          = (pixel *)_dst;
1217     ptrdiff_t dststride = _dststride / sizeof(pixel);
1218     const int8_t *filter = ff_hevc_epel_filters[mx - 1];
1219     int shift = 14 + 1 - BIT_DEPTH;
1220 #if BIT_DEPTH < 14
1221     int offset = 1 << (shift - 1);
1222 #else
1223     int offset = 0;
1224 #endif
1225
1226     for (y = 0; y < height; y++) {
1227         for (x = 0; x < width; x++) {
1228             dst[x] = av_clip_pixel(((EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8)) + src2[x] + offset) >> shift);
1229         }
1230         dst  += dststride;
1231         src  += srcstride;
1232         src2 += src2stride;
1233     }
1234 }
1235
1236 static void FUNC(put_hevc_epel_uni_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1237                                       int height, intptr_t mx, intptr_t my, int width)
1238 {
1239     int x, y;
1240     pixel *src = (pixel *)_src;
1241     ptrdiff_t srcstride  = _srcstride / sizeof(pixel);
1242     pixel *dst          = (pixel *)_dst;
1243     ptrdiff_t dststride = _dststride / sizeof(pixel);
1244     const int8_t *filter = ff_hevc_epel_filters[my - 1];
1245     int shift = 14 - BIT_DEPTH;
1246 #if BIT_DEPTH < 14
1247     int offset = 1 << (shift - 1);
1248 #else
1249     int offset = 0;
1250 #endif
1251
1252     for (y = 0; y < height; y++) {
1253         for (x = 0; x < width; x++)
1254             dst[x] = av_clip_pixel(((EPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8)) + offset) >> shift);
1255         src += srcstride;
1256         dst += dststride;
1257     }
1258 }
1259
1260 static void FUNC(put_hevc_epel_bi_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1261                                      int16_t *src2, ptrdiff_t src2stride,
1262                                      int height, intptr_t mx, intptr_t my, int width)
1263 {
1264     int x, y;
1265     pixel *src = (pixel *)_src;
1266     ptrdiff_t srcstride  = _srcstride / sizeof(pixel);
1267     const int8_t *filter = ff_hevc_epel_filters[my - 1];
1268     pixel *dst          = (pixel *)_dst;
1269     ptrdiff_t dststride = _dststride / sizeof(pixel);
1270     int shift = 14 + 1 - BIT_DEPTH;
1271 #if BIT_DEPTH < 14
1272     int offset = 1 << (shift - 1);
1273 #else
1274     int offset = 0;
1275 #endif
1276
1277     for (y = 0; y < height; y++) {
1278         for (x = 0; x < width; x++)
1279             dst[x] = av_clip_pixel(((EPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8)) + src2[x] + offset) >> shift);
1280         dst  += dststride;
1281         src  += srcstride;
1282         src2 += src2stride;
1283     }
1284 }
1285
1286 static void FUNC(put_hevc_epel_uni_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1287                                        int height, intptr_t mx, intptr_t my, int width)
1288 {
1289     int x, y;
1290     pixel *src = (pixel *)_src;
1291     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
1292     pixel *dst          = (pixel *)_dst;
1293     ptrdiff_t dststride = _dststride / sizeof(pixel);
1294     const int8_t *filter = ff_hevc_epel_filters[mx - 1];
1295     int16_t tmp_array[(MAX_PB_SIZE + EPEL_EXTRA) * MAX_PB_SIZE];
1296     int16_t *tmp = tmp_array;
1297     int shift = 14 - BIT_DEPTH;
1298 #if BIT_DEPTH < 14
1299     int offset = 1 << (shift - 1);
1300 #else
1301     int offset = 0;
1302 #endif
1303
1304     src -= EPEL_EXTRA_BEFORE * srcstride;
1305
1306     for (y = 0; y < height + EPEL_EXTRA; y++) {
1307         for (x = 0; x < width; x++)
1308             tmp[x] = EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
1309         src += srcstride;
1310         tmp += MAX_PB_SIZE;
1311     }
1312
1313     tmp      = tmp_array + EPEL_EXTRA_BEFORE * MAX_PB_SIZE;
1314     filter = ff_hevc_epel_filters[my - 1];
1315
1316     for (y = 0; y < height; y++) {
1317         for (x = 0; x < width; x++)
1318             dst[x] = av_clip_pixel(((EPEL_FILTER(tmp, MAX_PB_SIZE) >> 6) + offset) >> shift);
1319         tmp += MAX_PB_SIZE;
1320         dst += dststride;
1321     }
1322 }
1323
1324 static void FUNC(put_hevc_epel_bi_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1325                                       int16_t *src2, ptrdiff_t src2stride,
1326                                       int height, intptr_t mx, intptr_t my, int width)
1327 {
1328     int x, y;
1329     pixel *src = (pixel *)_src;
1330     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
1331     pixel *dst          = (pixel *)_dst;
1332     ptrdiff_t dststride = _dststride / sizeof(pixel);
1333     const int8_t *filter = ff_hevc_epel_filters[mx - 1];
1334     int16_t tmp_array[(MAX_PB_SIZE + EPEL_EXTRA) * MAX_PB_SIZE];
1335     int16_t *tmp = tmp_array;
1336     int shift = 14 + 1 - BIT_DEPTH;
1337 #if BIT_DEPTH < 14
1338     int offset = 1 << (shift - 1);
1339 #else
1340     int offset = 0;
1341 #endif
1342
1343     src -= EPEL_EXTRA_BEFORE * srcstride;
1344
1345     for (y = 0; y < height + EPEL_EXTRA; y++) {
1346         for (x = 0; x < width; x++)
1347             tmp[x] = EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
1348         src += srcstride;
1349         tmp += MAX_PB_SIZE;
1350     }
1351
1352     tmp      = tmp_array + EPEL_EXTRA_BEFORE * MAX_PB_SIZE;
1353     filter = ff_hevc_epel_filters[my - 1];
1354
1355     for (y = 0; y < height; y++) {
1356         for (x = 0; x < width; x++)
1357             dst[x] = av_clip_pixel(((EPEL_FILTER(tmp, MAX_PB_SIZE) >> 6) + src2[x] + offset) >> shift);
1358         tmp  += MAX_PB_SIZE;
1359         dst  += dststride;
1360         src2 += src2stride;
1361     }
1362 }
1363
1364 static void FUNC(put_hevc_epel_uni_w_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1365                                         int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width)
1366 {
1367     int x, y;
1368     pixel *src = (pixel *)_src;
1369     ptrdiff_t srcstride  = _srcstride / sizeof(pixel);
1370     pixel *dst          = (pixel *)_dst;
1371     ptrdiff_t dststride = _dststride / sizeof(pixel);
1372     const int8_t *filter = ff_hevc_epel_filters[mx - 1];
1373     int shift = denom + 14 - BIT_DEPTH;
1374 #if BIT_DEPTH < 14
1375     int offset = 1 << (shift - 1);
1376 #else
1377     int offset = 0;
1378 #endif
1379
1380     ox     = ox * (1 << (BIT_DEPTH - 8));
1381     for (y = 0; y < height; y++) {
1382         for (x = 0; x < width; x++) {
1383             dst[x] = av_clip_pixel((((EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8)) * wx + offset) >> shift) + ox);
1384         }
1385         dst += dststride;
1386         src += srcstride;
1387     }
1388 }
1389
1390 static void FUNC(put_hevc_epel_bi_w_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1391                                        int16_t *src2, ptrdiff_t src2stride,
1392                                        int height, int denom, int wx0, int wx1,
1393                                        int ox0, int ox1, intptr_t mx, intptr_t my, int width)
1394 {
1395     int x, y;
1396     pixel *src = (pixel *)_src;
1397     ptrdiff_t srcstride  = _srcstride / sizeof(pixel);
1398     pixel *dst          = (pixel *)_dst;
1399     ptrdiff_t dststride = _dststride / sizeof(pixel);
1400     const int8_t *filter = ff_hevc_epel_filters[mx - 1];
1401     int shift = 14 + 1 - BIT_DEPTH;
1402     int log2Wd = denom + shift - 1;
1403
1404     ox0     = ox0 * (1 << (BIT_DEPTH - 8));
1405     ox1     = ox1 * (1 << (BIT_DEPTH - 8));
1406     for (y = 0; y < height; y++) {
1407         for (x = 0; x < width; x++)
1408             dst[x] = av_clip_pixel(((EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8)) * wx1 + src2[x] * wx0 +
1409                                     ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1));
1410         src  += srcstride;
1411         dst  += dststride;
1412         src2 += src2stride;
1413     }
1414 }
1415
1416 static void FUNC(put_hevc_epel_uni_w_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1417                                         int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width)
1418 {
1419     int x, y;
1420     pixel *src = (pixel *)_src;
1421     ptrdiff_t srcstride  = _srcstride / sizeof(pixel);
1422     pixel *dst          = (pixel *)_dst;
1423     ptrdiff_t dststride = _dststride / sizeof(pixel);
1424     const int8_t *filter = ff_hevc_epel_filters[my - 1];
1425     int shift = denom + 14 - BIT_DEPTH;
1426 #if BIT_DEPTH < 14
1427     int offset = 1 << (shift - 1);
1428 #else
1429     int offset = 0;
1430 #endif
1431
1432     ox     = ox * (1 << (BIT_DEPTH - 8));
1433     for (y = 0; y < height; y++) {
1434         for (x = 0; x < width; x++) {
1435             dst[x] = av_clip_pixel((((EPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8)) * wx + offset) >> shift) + ox);
1436         }
1437         dst += dststride;
1438         src += srcstride;
1439     }
1440 }
1441
1442 static void FUNC(put_hevc_epel_bi_w_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1443                                        int16_t *src2, ptrdiff_t src2stride,
1444                                        int height, int denom, int wx0, int wx1,
1445                                        int ox0, int ox1, intptr_t mx, intptr_t my, int width)
1446 {
1447     int x, y;
1448     pixel *src = (pixel *)_src;
1449     ptrdiff_t srcstride  = _srcstride / sizeof(pixel);
1450     const int8_t *filter = ff_hevc_epel_filters[my - 1];
1451     pixel *dst          = (pixel *)_dst;
1452     ptrdiff_t dststride = _dststride / sizeof(pixel);
1453     int shift = 14 + 1 - BIT_DEPTH;
1454     int log2Wd = denom + shift - 1;
1455
1456     ox0     = ox0 * (1 << (BIT_DEPTH - 8));
1457     ox1     = ox1 * (1 << (BIT_DEPTH - 8));
1458     for (y = 0; y < height; y++) {
1459         for (x = 0; x < width; x++)
1460             dst[x] = av_clip_pixel(((EPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8)) * wx1 + src2[x] * wx0 +
1461                                     ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1));
1462         src  += srcstride;
1463         dst  += dststride;
1464         src2 += src2stride;
1465     }
1466 }
1467
1468 static void FUNC(put_hevc_epel_uni_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1469                                          int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width)
1470 {
1471     int x, y;
1472     pixel *src = (pixel *)_src;
1473     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
1474     pixel *dst          = (pixel *)_dst;
1475     ptrdiff_t dststride = _dststride / sizeof(pixel);
1476     const int8_t *filter = ff_hevc_epel_filters[mx - 1];
1477     int16_t tmp_array[(MAX_PB_SIZE + EPEL_EXTRA) * MAX_PB_SIZE];
1478     int16_t *tmp = tmp_array;
1479     int shift = denom + 14 - BIT_DEPTH;
1480 #if BIT_DEPTH < 14
1481     int offset = 1 << (shift - 1);
1482 #else
1483     int offset = 0;
1484 #endif
1485
1486     src -= EPEL_EXTRA_BEFORE * srcstride;
1487
1488     for (y = 0; y < height + EPEL_EXTRA; y++) {
1489         for (x = 0; x < width; x++)
1490             tmp[x] = EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
1491         src += srcstride;
1492         tmp += MAX_PB_SIZE;
1493     }
1494
1495     tmp      = tmp_array + EPEL_EXTRA_BEFORE * MAX_PB_SIZE;
1496     filter = ff_hevc_epel_filters[my - 1];
1497
1498     ox     = ox * (1 << (BIT_DEPTH - 8));
1499     for (y = 0; y < height; y++) {
1500         for (x = 0; x < width; x++)
1501             dst[x] = av_clip_pixel((((EPEL_FILTER(tmp, MAX_PB_SIZE) >> 6) * wx + offset) >> shift) + ox);
1502         tmp += MAX_PB_SIZE;
1503         dst += dststride;
1504     }
1505 }
1506
1507 static void FUNC(put_hevc_epel_bi_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
1508                                         int16_t *src2, ptrdiff_t src2stride,
1509                                         int height, int denom, int wx0, int wx1,
1510                                         int ox0, int ox1, intptr_t mx, intptr_t my, int width)
1511 {
1512     int x, y;
1513     pixel *src = (pixel *)_src;
1514     ptrdiff_t srcstride = _srcstride / sizeof(pixel);
1515     pixel *dst          = (pixel *)_dst;
1516     ptrdiff_t dststride = _dststride / sizeof(pixel);
1517     const int8_t *filter = ff_hevc_epel_filters[mx - 1];
1518     int16_t tmp_array[(MAX_PB_SIZE + EPEL_EXTRA) * MAX_PB_SIZE];
1519     int16_t *tmp = tmp_array;
1520     int shift = 14 + 1 - BIT_DEPTH;
1521     int log2Wd = denom + shift - 1;
1522
1523     src -= EPEL_EXTRA_BEFORE * srcstride;
1524
1525     for (y = 0; y < height + EPEL_EXTRA; y++) {
1526         for (x = 0; x < width; x++)
1527             tmp[x] = EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
1528         src += srcstride;
1529         tmp += MAX_PB_SIZE;
1530     }
1531
1532     tmp      = tmp_array + EPEL_EXTRA_BEFORE * MAX_PB_SIZE;
1533     filter = ff_hevc_epel_filters[my - 1];
1534
1535     ox0     = ox0 * (1 << (BIT_DEPTH - 8));
1536     ox1     = ox1 * (1 << (BIT_DEPTH - 8));
1537     for (y = 0; y < height; y++) {
1538         for (x = 0; x < width; x++)
1539             dst[x] = av_clip_pixel(((EPEL_FILTER(tmp, MAX_PB_SIZE) >> 6) * wx1 + src2[x] * wx0 +
1540                                     ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1));
1541         tmp  += MAX_PB_SIZE;
1542         dst  += dststride;
1543         src2 += src2stride;
1544     }
1545 }// line zero
1546 #define P3 pix[-4 * xstride]
1547 #define P2 pix[-3 * xstride]
1548 #define P1 pix[-2 * xstride]
1549 #define P0 pix[-1 * xstride]
1550 #define Q0 pix[0 * xstride]
1551 #define Q1 pix[1 * xstride]
1552 #define Q2 pix[2 * xstride]
1553 #define Q3 pix[3 * xstride]
1554
1555 // line three. used only for deblocking decision
1556 #define TP3 pix[-4 * xstride + 3 * ystride]
1557 #define TP2 pix[-3 * xstride + 3 * ystride]
1558 #define TP1 pix[-2 * xstride + 3 * ystride]
1559 #define TP0 pix[-1 * xstride + 3 * ystride]
1560 #define TQ0 pix[0  * xstride + 3 * ystride]
1561 #define TQ1 pix[1  * xstride + 3 * ystride]
1562 #define TQ2 pix[2  * xstride + 3 * ystride]
1563 #define TQ3 pix[3  * xstride + 3 * ystride]
1564
1565 static void FUNC(hevc_loop_filter_luma)(uint8_t *_pix,
1566                                         ptrdiff_t _xstride, ptrdiff_t _ystride,
1567                                         int beta, int *_tc,
1568                                         uint8_t *_no_p, uint8_t *_no_q)
1569 {
1570     int d, j;
1571     pixel *pix        = (pixel *)_pix;
1572     ptrdiff_t xstride = _xstride / sizeof(pixel);
1573     ptrdiff_t ystride = _ystride / sizeof(pixel);
1574
1575     beta <<= BIT_DEPTH - 8;
1576
1577     for (j = 0; j < 2; j++) {
1578         const int dp0  = abs(P2  - 2 * P1  + P0);
1579         const int dq0  = abs(Q2  - 2 * Q1  + Q0);
1580         const int dp3  = abs(TP2 - 2 * TP1 + TP0);
1581         const int dq3  = abs(TQ2 - 2 * TQ1 + TQ0);
1582         const int d0   = dp0 + dq0;
1583         const int d3   = dp3 + dq3;
1584         const int tc   = _tc[j]   << (BIT_DEPTH - 8);
1585         const int no_p = _no_p[j];
1586         const int no_q = _no_q[j];
1587
1588         if (d0 + d3 >= beta) {
1589             pix += 4 * ystride;
1590             continue;
1591         } else {
1592             const int beta_3 = beta >> 3;
1593             const int beta_2 = beta >> 2;
1594             const int tc25   = ((tc * 5 + 1) >> 1);
1595
1596             if (abs(P3  -  P0) + abs(Q3  -  Q0) < beta_3 && abs(P0  -  Q0) < tc25 &&
1597                 abs(TP3 - TP0) + abs(TQ3 - TQ0) < beta_3 && abs(TP0 - TQ0) < tc25 &&
1598                                       (d0 << 1) < beta_2 &&      (d3 << 1) < beta_2) {
1599                 // strong filtering
1600                 const int tc2 = tc << 1;
1601                 for (d = 0; d < 4; d++) {
1602                     const int p3 = P3;
1603                     const int p2 = P2;
1604                     const int p1 = P1;
1605                     const int p0 = P0;
1606                     const int q0 = Q0;
1607                     const int q1 = Q1;
1608                     const int q2 = Q2;
1609                     const int q3 = Q3;
1610                     if (!no_p) {
1611                         P0 = p0 + av_clip(((p2 + 2 * p1 + 2 * p0 + 2 * q0 + q1 + 4) >> 3) - p0, -tc2, tc2);
1612                         P1 = p1 + av_clip(((p2 + p1 + p0 + q0 + 2) >> 2) - p1, -tc2, tc2);
1613                         P2 = p2 + av_clip(((2 * p3 + 3 * p2 + p1 + p0 + q0 + 4) >> 3) - p2, -tc2, tc2);
1614                     }
1615                     if (!no_q) {
1616                         Q0 = q0 + av_clip(((p1 + 2 * p0 + 2 * q0 + 2 * q1 + q2 + 4) >> 3) - q0, -tc2, tc2);
1617                         Q1 = q1 + av_clip(((p0 + q0 + q1 + q2 + 2) >> 2) - q1, -tc2, tc2);
1618                         Q2 = q2 + av_clip(((2 * q3 + 3 * q2 + q1 + q0 + p0 + 4) >> 3) - q2, -tc2, tc2);
1619                     }
1620                     pix += ystride;
1621                 }
1622             } else { // normal filtering
1623                 int nd_p = 1;
1624                 int nd_q = 1;
1625                 const int tc_2 = tc >> 1;
1626                 if (dp0 + dp3 < ((beta + (beta >> 1)) >> 3))
1627                     nd_p = 2;
1628                 if (dq0 + dq3 < ((beta + (beta >> 1)) >> 3))
1629                     nd_q = 2;
1630
1631                 for (d = 0; d < 4; d++) {
1632                     const int p2 = P2;
1633                     const int p1 = P1;
1634                     const int p0 = P0;
1635                     const int q0 = Q0;
1636                     const int q1 = Q1;
1637                     const int q2 = Q2;
1638                     int delta0   = (9 * (q0 - p0) - 3 * (q1 - p1) + 8) >> 4;
1639                     if (abs(delta0) < 10 * tc) {
1640                         delta0 = av_clip(delta0, -tc, tc);
1641                         if (!no_p)
1642                             P0 = av_clip_pixel(p0 + delta0);
1643                         if (!no_q)
1644                             Q0 = av_clip_pixel(q0 - delta0);
1645                         if (!no_p && nd_p > 1) {
1646                             const int deltap1 = av_clip((((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1, -tc_2, tc_2);
1647                             P1 = av_clip_pixel(p1 + deltap1);
1648                         }
1649                         if (!no_q && nd_q > 1) {
1650                             const int deltaq1 = av_clip((((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1, -tc_2, tc_2);
1651                             Q1 = av_clip_pixel(q1 + deltaq1);
1652                         }
1653                     }
1654                     pix += ystride;
1655                 }
1656             }
1657         }
1658     }
1659 }
1660
1661 static void FUNC(hevc_loop_filter_chroma)(uint8_t *_pix, ptrdiff_t _xstride,
1662                                           ptrdiff_t _ystride, int *_tc,
1663                                           uint8_t *_no_p, uint8_t *_no_q)
1664 {
1665     int d, j, no_p, no_q;
1666     pixel *pix        = (pixel *)_pix;
1667     ptrdiff_t xstride = _xstride / sizeof(pixel);
1668     ptrdiff_t ystride = _ystride / sizeof(pixel);
1669
1670     for (j = 0; j < 2; j++) {
1671         const int tc = _tc[j] << (BIT_DEPTH - 8);
1672         if (tc <= 0) {
1673             pix += 4 * ystride;
1674             continue;
1675         }
1676         no_p = _no_p[j];
1677         no_q = _no_q[j];
1678
1679         for (d = 0; d < 4; d++) {
1680             int delta0;
1681             const int p1 = P1;
1682             const int p0 = P0;
1683             const int q0 = Q0;
1684             const int q1 = Q1;
1685             delta0 = av_clip((((q0 - p0) * 4) + p1 - q1 + 4) >> 3, -tc, tc);
1686             if (!no_p)
1687                 P0 = av_clip_pixel(p0 + delta0);
1688             if (!no_q)
1689                 Q0 = av_clip_pixel(q0 - delta0);
1690             pix += ystride;
1691         }
1692     }
1693 }
1694
1695 static void FUNC(hevc_h_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
1696                                             int32_t *tc, uint8_t *no_p,
1697                                             uint8_t *no_q)
1698 {
1699     FUNC(hevc_loop_filter_chroma)(pix, stride, sizeof(pixel), tc, no_p, no_q);
1700 }
1701
1702 static void FUNC(hevc_v_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
1703                                             int32_t *tc, uint8_t *no_p,
1704                                             uint8_t *no_q)
1705 {
1706     FUNC(hevc_loop_filter_chroma)(pix, sizeof(pixel), stride, tc, no_p, no_q);
1707 }
1708
1709 static void FUNC(hevc_h_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
1710                                           int beta, int32_t *tc, uint8_t *no_p,
1711                                           uint8_t *no_q)
1712 {
1713     FUNC(hevc_loop_filter_luma)(pix, stride, sizeof(pixel),
1714                                 beta, tc, no_p, no_q);
1715 }
1716
1717 static void FUNC(hevc_v_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
1718                                           int beta, int32_t *tc, uint8_t *no_p,
1719                                           uint8_t *no_q)
1720 {
1721     FUNC(hevc_loop_filter_luma)(pix, sizeof(pixel), stride,
1722                                 beta, tc, no_p, no_q);
1723 }
1724
1725 #undef P3
1726 #undef P2
1727 #undef P1
1728 #undef P0
1729 #undef Q0
1730 #undef Q1
1731 #undef Q2
1732 #undef Q3
1733
1734 #undef TP3
1735 #undef TP2
1736 #undef TP1
1737 #undef TP0
1738 #undef TQ0
1739 #undef TQ1
1740 #undef TQ2
1741 #undef TQ3