[PR] avcodec/x86/hevc: add SSE2 ref_filter_3tap (PR #24271)
Marcos Ashton via ffmpeg-devel <[email protected]>
| Newsgroups | gmane.comp.video.ffmpeg.devel |
|---|---|
| Message-ID | <[email protected]> |
PR #24271 opened by Marcos Ashton (MarcosAsh) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24271 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24271.patch Adds an x86 SIMD implementation of the HEVC intra reference sample smoothing filter (previously C-only), for 8 bit, as part of #23022. This is the second of the five intra prediction groups x86 was missing; aarch64 NEON already covers it. The filter is `out[i] = (in[i-1] + 2*in[i] + in[i+1] + 2) >> 2` over 2*size samples of each reference array, and it stays exact in the byte domain with no widening to words. pavgb rounds up, so the low bit of in[i-1]+in[i+1] is cleared before the second average. The result then equals the C expression for every byte triple, which I checked exhaustively over all 16.7M combinations. Two edges need care. The last sample is copied rather than filtered, and is selected into the final 16 byte store rather than patched afterwards, since the destination array has no room past it. The corner sample, which both reference arrays share, is written as a dword rather than a byte. x86-32 has no byte addressable register left once the four pointers are in place, and the three bytes past the corner belong to the filtered range and are rewritten immediately after. SSE2 is the baseline rather than SSSE3. The reference arrays are plain stack arrays with the pointer offset by one sample, so nothing can be assumed aligned. Three unaligned loads beat one load plus two palignr, and pshufb has nothing to do here either. The last block reads in[2*size], which the input arrays carry 16 samples of slack for; its result is discarded. The NEON version reads considerably further into the same slack. checkasm -t hevc_pred passes bit-exact, including 200 runs with different seeds. Benchmarks (Core Ultra 7 155H): ``` hevc_ref_filter_3tap_8x8_8_c: 75.5 hevc_ref_filter_3tap_8x8_8_sse2: 7.1 (10.49x) hevc_ref_filter_3tap_16x16_8_c: 187.7 hevc_ref_filter_3tap_16x16_8_sse2: 12.0 (15.57x) hevc_ref_filter_3tap_32x32_8_c: 348.0 hevc_ref_filter_3tap_32x32_8_sse2: 22.2 (15.37x) ``` Stacked on #24052, which adds pred_init.c and the init hook, so that commit shows up here too until it merges. >From 655f18e2dfadd672d06a1a0b8910ad4e9a5e2cad Mon Sep 17 00:00:00 2001 From: Marcos Ashton Iglesias <[email protected]> Date: Fri, 7 Aug 2026 20:42:41 +0100 Subject: [PATCH 1/2] avcodec/x86/hevc: add SSSE3 pred_planar Implements planar intra prediction for 8 bit. x86 has no HEVC intra prediction at all; aarch64 NEON already covers planar, DC and angular. Every term except (size-1-x)*left[y] is linear in y, so for a group of eight columns they collapse into one running accumulator whose increment left[size]-top[x] is loop invariant. Running columns outermost keeps that accumulator and its delta in registers, so a row costs one pmullw and two paddw with no reload of top[]. 16x16 and 32x32 run two groups together, sharing the left[y] broadcast and writing a row with one 16 byte store. Words suffice throughout: each coefficient pair sums to size, so the largest value is 2*32*255 + 32 = 16352. SSSE3 rather than SSE2 since pshufb does the broadcasts and the byte to word widening. checkasm --bench on a Core Ultra 7 155H: hevc_pred_planar_4x4_8_c: 18.4 hevc_pred_planar_4x4_8_ssse3: 5.5 ( 3.35x) hevc_pred_planar_8x8_8_c: 83.1 hevc_pred_planar_8x8_8_ssse3: 16.3 ( 5.10x) hevc_pred_planar_16x16_8_c: 224.8 hevc_pred_planar_16x16_8_ssse3: 47.3 ( 4.75x) hevc_pred_planar_32x32_8_c: 629.5 hevc_pred_planar_32x32_8_ssse3: 196.5 ( 3.20x) Part of #23022. --- libavcodec/hevc/pred.c | 3 + libavcodec/hevc/pred.h | 1 + libavcodec/x86/hevc/Makefile | 2 + libavcodec/x86/hevc/pred.asm | 201 ++++++++++++++++++++++++++++++++ libavcodec/x86/hevc/pred_init.c | 51 ++++++++ 5 files changed, 258 insertions(+) create mode 100644 libavcodec/x86/hevc/pred.asm create mode 100644 libavcodec/x86/hevc/pred_init.c diff --git a/libavcodec/hevc/pred.c b/libavcodec/hevc/pred.c index 037cbc413f..673c02d856 100644 --- a/libavcodec/hevc/pred.c +++ b/libavcodec/hevc/pred.c @@ -85,4 +85,7 @@ void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth) #if ARCH_MIPS ff_hevc_pred_init_mips(hpc, bit_depth); #endif +#if ARCH_X86 && HAVE_X86ASM + ff_hevc_pred_init_x86(hpc, bit_depth); +#endif } diff --git a/libavcodec/hevc/pred.h b/libavcodec/hevc/pred.h index 849806fefb..9c0cf17349 100644 --- a/libavcodec/hevc/pred.h +++ b/libavcodec/hevc/pred.h @@ -51,6 +51,7 @@ typedef struct HEVCPredContext { void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth); void ff_hevc_pred_init_mips(HEVCPredContext *hpc, int bit_depth); void ff_hevc_pred_init_aarch64(HEVCPredContext *hpc, int bit_depth); +void ff_hevc_pred_init_x86(HEVCPredContext *hpc, int bit_depth); /* C angular prediction fallbacks (non-static for arch-specific partial override) */ #define HEVC_PRED_ANGULAR_DECL(depth) \ diff --git a/libavcodec/x86/hevc/Makefile b/libavcodec/x86/hevc/Makefile index d09c613a19..0ac5287bdc 100644 --- a/libavcodec/x86/hevc/Makefile +++ b/libavcodec/x86/hevc/Makefile @@ -7,6 +7,8 @@ X86ASM-OBJS-$(CONFIG_HEVC_DECODER) += x86/hevc/dsp_init.o \ x86/hevc/dequant.o \ x86/hevc/idct.o \ x86/hevc/mc.o \ + x86/hevc/pred.o \ + x86/hevc/pred_init.o \ x86/hevc/sao.o \ x86/hevc/sao_10bit.o \ x86/h26x/h2656dsp.o \ diff --git a/libavcodec/x86/hevc/pred.asm b/libavcodec/x86/hevc/pred.asm new file mode 100644 index 0000000000..2e07c5f759 --- /dev/null +++ b/libavcodec/x86/hevc/pred.asm @@ -0,0 +1,201 @@ +;****************************************************************************** +;* SIMD-optimized HEVC intra prediction +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA 16 + +; planar weights: (size - 1 - x) is a suffix of pw_desc, (x + 1) a prefix of pw_asc +pw_desc: dw 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16 + dw 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +pw_asc: dw 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + dw 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 + +; pshufb masks: zero-extend bytes to words without a dedicated zero register +pb_bcastw0: times 8 db 0, -1 ; byte 0 -> all eight words +pb_widen: db 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, 7, -1 + +; 4x4-specific: two rows per register +pb_top4dup: db 0, -1, 1, -1, 2, -1, 3, -1, 0, -1, 1, -1, 2, -1, 3, -1 +pb_left01: db 0, -1, 0, -1, 0, -1, 0, -1, 1, -1, 1, -1, 1, -1, 1, -1 +pb_left23: db 2, -1, 2, -1, 2, -1, 2, -1, 3, -1, 3, -1, 3, -1, 3, -1 +pw_planar4_a: dw 3, 2, 1, 0, 3, 2, 1, 0 ; size - 1 - x +pw_planar4_b: dw 1, 2, 3, 4, 1, 2, 3, 4 ; x + 1 +pw_planar4_vy0: dw 3, 3, 3, 3, 2, 2, 2, 2 ; size - 1 - y, rows 0-1 +pw_planar4_vy1: dw 1, 1, 1, 1, 0, 0, 0, 0 ; rows 2-3 +pw_planar4_yb0: dw 1, 1, 1, 1, 2, 2, 2, 2 ; y + 1, rows 0-1 +pw_planar4_yb1: dw 3, 3, 3, 3, 4, 4, 4, 4 ; rows 2-3 + +cextern pw_4 +cextern pw_8 +cextern pw_16 +cextern pw_32 + +SECTION .text + +;----------------------------------------------------------------------------- +; void ff_hevc_pred_planar_<idx>_8(uint8_t *src, const uint8_t *top, +; const uint8_t *left, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +; src[y*stride + x] = ((size-1-x)*left[y] + (x+1)*top[size] + +; (size-1-y)*top[x] + (y+1)*left[size] + size) >> (log2 + 1) +; +; Every term but (size-1-x)*left[y] is linear in y, so for eight columns they +; collapse into one accumulator with the loop-invariant step left[size]-top[x]. +; Running columns outermost keeps both in registers: a row costs one pmullw and +; two paddw with no reload of top[]. Words suffice, as each coefficient pair +; sums to size and the largest value is 2*32*255 + 32 = 16352 < 2^15. + +; Set up the running accumulator for the eight columns starting at %6. +; (size-1)*top[x] is formed as (top[x] << log2) - top[x] so that no vector of +; size-1 has to be materialised. +; %1 = sum, %2 = delta, %3 = temp, %4 = size, %5 = index, %6 = first column +%macro PLANAR_INIT 6 + movd %1, [topq + %4] + pshufb %1, [pb_bcastw0] ; top[size] + pmullw %1, [pw_asc + (%6) * 2] ; (x+1)*top[size] + movd %2, [leftq + %4] + pshufb %2, [pb_bcastw0] ; left[size] + paddw %1, %2 + paddw %1, [pw_ %+ %4] ; + left[size] + size + movq %3, [topq + (%6)] + pshufb %3, [pb_widen] ; top[x] + psubw %2, %3 ; delta = left[size] - top[x] + psubw %1, %3 + psllw %3, (%5) + 2 + paddw %1, %3 ; + (size-1)*top[x] = sum(0) +%endmacro + +; One group of eight columns, for the block size that is only eight wide. +; %1 = block size, %2 = index, %3 = first column +%macro PLANAR_CHUNK 3 + PLANAR_INIT m0, m1, m2, %1, %2, %3 + lea srcq, [baseq + %3] + xor yd, yd +%%loop: + movd m2, [leftq + yq] + pshufb m2, [pb_bcastw0] ; left[y] + pmullw m2, [pw_desc + (32 - %1 + %3) * 2] ; (size-1-x)*left[y] + paddw m2, m0 + psrlw m2, %2 + 3 + packuswb m2, m2 + movq [srcq], m2 + add srcq, strideq + paddw m0, m1 + inc yd + cmp yd, %1 + jl %%loop +%endmacro + +; Two adjacent groups at once, so that a row is written with a single 16 byte +; store and the left[y] broadcast is shared between them. +; %1 = block size, %2 = index, %3 = first column +%macro PLANAR_CHUNK2 3 + PLANAR_INIT m0, m1, m4, %1, %2, %3 + PLANAR_INIT m2, m3, m4, %1, %2, %3 + 8 + lea srcq, [baseq + %3] + xor yd, yd +%%loop: + movd m4, [leftq + yq] + pshufb m4, [pb_bcastw0] ; left[y] + mova m5, m4 + pmullw m4, [pw_desc + (32 - %1 + %3) * 2] + paddw m4, m0 + psrlw m4, %2 + 3 + pmullw m5, [pw_desc + (32 - %1 + %3 + 8) * 2] + paddw m5, m2 + psrlw m5, %2 + 3 + packuswb m4, m5 + movu [srcq], m4 + add srcq, strideq + paddw m0, m1 + paddw m2, m3 + inc yd + cmp yd, %1 + jl %%loop +%endmacro + +; %1 = block size, %2 = pred_planar index (log2(size) - 2) +%macro PRED_PLANAR 2 +cglobal hevc_pred_planar_%2_8, 4, 6, 6, src, top, left, stride, base, y + mov baseq, srcq +%if %1 == 8 + PLANAR_CHUNK %1, %2, 0 +%else +%assign %%off 0 +%rep %1 / 16 + PLANAR_CHUNK2 %1, %2, %%off +%assign %%off %%off + 16 +%endrep +%endif + RET +%endmacro + +; 4x4: fully unrolled, two rows per register +%macro PRED_PLANAR4 0 +cglobal hevc_pred_planar_0_8, 4, 4, 5, src, top, left, stride + movd m0, [topq + 4] + pshufb m0, [pb_bcastw0] ; top[4] + pmullw m0, [pw_planar4_b] ; (x+1)*top[4] + mova m1, m0 + movd m2, [leftq + 4] + pshufb m2, [pb_bcastw0] ; left[4] + mova m3, m2 + pmullw m3, [pw_planar4_yb0] + paddw m0, m3 + paddw m0, [pw_4] ; row-invariant terms, rows 0-1 + pmullw m2, [pw_planar4_yb1] + paddw m1, m2 + paddw m1, [pw_4] ; rows 2-3 + movd m2, [topq] + pshufb m2, [pb_top4dup] ; top[0..3], both halves + movd m3, [leftq] + mova m4, m3 + pshufb m3, [pb_left01] ; left[0] x4 | left[1] x4 + pshufb m4, [pb_left23] ; left[2] x4 | left[3] x4 + pmullw m3, [pw_planar4_a] + paddw m3, m0 + mova m0, m2 + pmullw m0, [pw_planar4_vy0] + paddw m3, m0 + psrlw m3, 3 + pmullw m4, [pw_planar4_a] + paddw m4, m1 + pmullw m2, [pw_planar4_vy1] + paddw m4, m2 + psrlw m4, 3 + packuswb m3, m4 + movd [srcq], m3 + psrldq m3, 4 + movd [srcq + strideq], m3 + lea srcq, [srcq + strideq * 2] + psrldq m3, 4 + movd [srcq], m3 + psrldq m3, 4 + movd [srcq + strideq], m3 + RET +%endmacro + +INIT_XMM ssse3 +PRED_PLANAR4 +PRED_PLANAR 8, 1 +PRED_PLANAR 16, 2 +PRED_PLANAR 32, 3 diff --git a/libavcodec/x86/hevc/pred_init.c b/libavcodec/x86/hevc/pred_init.c new file mode 100644 index 0000000000..980e28b861 --- /dev/null +++ b/libavcodec/x86/hevc/pred_init.c @@ -0,0 +1,51 @@ +/* + * SIMD-optimized HEVC intra prediction + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/hevc/pred.h" + +#define PRED_PLANAR_FUNC(idx, opt) \ +void ff_hevc_pred_planar_ ## idx ## _8_ ## opt(uint8_t *src, \ + const uint8_t *top, \ + const uint8_t *left, \ + ptrdiff_t stride); + +PRED_PLANAR_FUNC(0, ssse3) +PRED_PLANAR_FUNC(1, ssse3) +PRED_PLANAR_FUNC(2, ssse3) +PRED_PLANAR_FUNC(3, ssse3) + +av_cold void ff_hevc_pred_init_x86(HEVCPredContext *hpc, int bit_depth) +{ + int cpu_flags = av_get_cpu_flags(); + + if (bit_depth == 8) { + if (EXTERNAL_SSSE3(cpu_flags)) { + hpc->pred_planar[0] = ff_hevc_pred_planar_0_8_ssse3; + hpc->pred_planar[1] = ff_hevc_pred_planar_1_8_ssse3; + hpc->pred_planar[2] = ff_hevc_pred_planar_2_8_ssse3; + hpc->pred_planar[3] = ff_hevc_pred_planar_3_8_ssse3; + } + } +} -- 2.52.0 >From 1b6743b23f9e836699d872c74687342096d5aa5d Mon Sep 17 00:00:00 2001 From: Marcos Ashton Iglesias <[email protected]> Date: Tue, 25 Aug 2026 21:51:49 +0100 Subject: [PATCH 2/2] avcodec/x86/hevc: add SSE2 ref_filter_3tap Smooths the intra reference samples for 8 bit, the second of the HEVC intra prediction groups x86 was missing; aarch64 NEON already has it. out[i] = (in[i-1] + 2*in[i] + in[i+1] + 2) >> 2 is exact in bytes. pavgb rounds up, so clearing the low bit of in[i-1]+in[i+1] before the second average gives the wanted result for every triple. The last sample is copied rather than filtered and is selected into the final store, since the destination has no room past it. The corner, which both arrays share, goes out as a dword because x86-32 has no byte register to spare here. SSE2 rather than SSSE3: nothing can be assumed aligned, so three unaligned loads beat a load plus two palignr. checkasm --bench on a Core Ultra 7 155H: hevc_ref_filter_3tap_8x8_8_c: 75.5 hevc_ref_filter_3tap_8x8_8_sse2: 7.1 (10.49x) hevc_ref_filter_3tap_16x16_8_c: 187.7 hevc_ref_filter_3tap_16x16_8_sse2: 12.0 (15.57x) hevc_ref_filter_3tap_32x32_8_c: 348.0 hevc_ref_filter_3tap_32x32_8_sse2: 22.2 (15.37x) Part of #23022. --- libavcodec/x86/hevc/pred.asm | 71 +++++++++++++++++++++++++++++++++ libavcodec/x86/hevc/pred_init.c | 16 ++++++++ 2 files changed, 87 insertions(+) diff --git a/libavcodec/x86/hevc/pred.asm b/libavcodec/x86/hevc/pred.asm index 2e07c5f759..3d1feee89f 100644 --- a/libavcodec/x86/hevc/pred.asm +++ b/libavcodec/x86/hevc/pred.asm @@ -43,6 +43,7 @@ pw_planar4_vy1: dw 1, 1, 1, 1, 0, 0, 0, 0 ; rows 2-3 pw_planar4_yb0: dw 1, 1, 1, 1, 2, 2, 2, 2 ; y + 1, rows 0-1 pw_planar4_yb1: dw 3, 3, 3, 3, 4, 4, 4, 4 ; rows 2-3 +cextern pb_1 cextern pw_4 cextern pw_8 cextern pw_16 @@ -199,3 +200,73 @@ PRED_PLANAR4 PRED_PLANAR 8, 1 PRED_PLANAR 16, 2 PRED_PLANAR 32, 3 + +;----------------------------------------------------------------------------- +; void ff_hevc_ref_filter_3tap_<size>x<size>_8(uint8_t *filtered_left, +; uint8_t *filtered_top, +; const uint8_t *left, +; const uint8_t *top, int size) +;----------------------------------------------------------------------------- + +; out[i] = (in[i-1] + 2*in[i] + in[i+1] + 2) >> 2, exact in bytes: pavgb rounds +; up, so clearing the low bit of in[i-1]+in[i+1] before the second average +; gives the wanted result for every triple. +; Nothing can be assumed aligned - plain stack arrays, pointers offset by one - +; so three unaligned loads beat a load plus two palignr and this stays SSE2. +; The last block reads in[2*size]; the input arrays carry 16 samples of slack +; for that, and its result is discarded. +; %1 = dst, %2 = src, %3 = offset. Leaves in[i] in m1 for the caller. +%macro FILTER_3TAP_16 3 + movu m0, [%2 + (%3) - 1] + movu m1, [%2 + (%3) + 1] + pxor m2, m0, m1 + pavgb m0, m1 + pand m2, m3 + psubb m0, m2 ; (in[i-1] + in[i+1]) >> 1 + movu m1, [%2 + (%3)] + pavgb m0, m1 +%endmacro + +; %1 = dst, %2 = src, %3 = 2 * size +%macro FILTER_3TAP_ARRAY 3 +%assign %%i 0 +%rep (%3) / 16 + FILTER_3TAP_16 %1, %2, %%i +%if %%i == (%3) - 16 + pxor m1, m0 ; last sample is copied, not + pand m1, m4 ; filtered; select it out of m1 as + pxor m0, m1 ; the dst has no room past it +%endif + movu [%1 + %%i], m0 +%assign %%i %%i + 16 +%endrep +%endmacro + +; %1 = size +%macro REF_FILTER_3TAP 1 +%assign %%n 2 * %1 +cglobal hevc_ref_filter_3tap_%1x%1_8, 4, 6, 5, fleft, ftop, left, top + ; The corner is shared by both arrays. Store it as a dword: x86-32 has no + ; byte register to spare here, and the 3 bytes past it are filtered below. + movzx r4d, byte [leftq - 1] + movzx r5d, byte [leftq] + lea r5, [r5 + r4*2 + 2] + movzx r4d, byte [topq] + add r5d, r4d + shr r5d, 2 + mov [fleftq - 1], r5d + mov [ftopq - 1], r5d + + mova m3, [pb_1] + pcmpeqb m4, m4 + pslldq m4, 15 ; selects the copied last sample + + FILTER_3TAP_ARRAY fleftq, leftq, %%n + FILTER_3TAP_ARRAY ftopq, topq, %%n + RET +%endmacro + +INIT_XMM sse2 +REF_FILTER_3TAP 8 +REF_FILTER_3TAP 16 +REF_FILTER_3TAP 32 diff --git a/libavcodec/x86/hevc/pred_init.c b/libavcodec/x86/hevc/pred_init.c index 980e28b861..65b8190c2a 100644 --- a/libavcodec/x86/hevc/pred_init.c +++ b/libavcodec/x86/hevc/pred_init.c @@ -36,11 +36,27 @@ PRED_PLANAR_FUNC(1, ssse3) PRED_PLANAR_FUNC(2, ssse3) PRED_PLANAR_FUNC(3, ssse3) +#define REF_FILTER_3TAP_FUNC(w, opt) \ +void ff_hevc_ref_filter_3tap_ ## w ## x ## w ## _8_ ## opt( \ + uint8_t *filtered_left, \ + uint8_t *filtered_top, \ + const uint8_t *left, \ + const uint8_t *top, int size); + +REF_FILTER_3TAP_FUNC( 8, sse2) +REF_FILTER_3TAP_FUNC(16, sse2) +REF_FILTER_3TAP_FUNC(32, sse2) + av_cold void ff_hevc_pred_init_x86(HEVCPredContext *hpc, int bit_depth) { int cpu_flags = av_get_cpu_flags(); if (bit_depth == 8) { + if (EXTERNAL_SSE2(cpu_flags)) { + hpc->ref_filter_3tap[0] = ff_hevc_ref_filter_3tap_8x8_8_sse2; + hpc->ref_filter_3tap[1] = ff_hevc_ref_filter_3tap_16x16_8_sse2; + hpc->ref_filter_3tap[2] = ff_hevc_ref_filter_3tap_32x32_8_sse2; + } if (EXTERNAL_SSSE3(cpu_flags)) { hpc->pred_planar[0] = ff_hevc_pred_planar_0_8_ssse3; hpc->pred_planar[1] = ff_hevc_pred_planar_1_8_ssse3; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]