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