/work/svt-av1/Source/Lib/Codec/cdef_copy.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2025, Alliance for Open Media. All rights reserved |
3 | | * |
4 | | * This source code is subject to the terms of the BSD 2 Clause License and |
5 | | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
6 | | * was not distributed with this source code in the LICENSE file, you can |
7 | | * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
8 | | * Media Patent License 1.0 was not distributed with this source code in the |
9 | | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
10 | | */ |
11 | | |
12 | | // CDEF pixel-copy helpers. Portable C (no target intrinsics): the 8-bit gather copy dispatches on |
13 | | // its (small, fixed) set of widths to constant-size memcpy, which the compiler lowers to optimal |
14 | | // inline load/stores on every target. |
15 | | |
16 | | #ifndef EbCdefCopy_h |
17 | | #define EbCdefCopy_h |
18 | | |
19 | | #include <stdint.h> |
20 | | #include <string.h> |
21 | | |
22 | | #include "svt_malloc.h" // svt_aom_memset16 |
23 | | |
24 | | // 8-bit recon -> padded src8 rect copy. The CDEF gather (apply + native-8 search) only ever uses the |
25 | | // widths enumerated below (all CDEF reads are +/-CDEF_HALO, so body is hsz+2*HALO and halo strips are |
26 | | // HALO). Dispatch ONCE per call to a constant-size memcpy loop so each row folds to optimal inline |
27 | | // load/stores on arm64 AND x86 -- no per-row libc memmove call, no target intrinsics. |
28 | | static inline void svt_cdef_copy_rect8(uint8_t* dst, int dstride, const uint8_t* src, int src_voffset, int src_hoffset, |
29 | 0 | int sstride, int v, int h) { |
30 | 0 | const uint8_t* base = &src[src_voffset * sstride + src_hoffset]; |
31 | 0 | #define CDEF_RECT_CW(W) \ |
32 | 0 | do { \ |
33 | 0 | for (int _r = 0; _r < v; _r++) { \ |
34 | 0 | memcpy(dst, base, (W)); \ |
35 | 0 | dst += dstride; \ |
36 | 0 | base += sstride; \ |
37 | 0 | } \ |
38 | 0 | } while (0) |
39 | 0 | switch (h) { |
40 | 0 | case 2: |
41 | 0 | CDEF_RECT_CW(2); |
42 | 0 | return; |
43 | 0 | case 32: |
44 | 0 | CDEF_RECT_CW(32); |
45 | 0 | return; |
46 | 0 | case 34: |
47 | 0 | CDEF_RECT_CW(34); |
48 | 0 | return; |
49 | 0 | case 36: |
50 | 0 | CDEF_RECT_CW(36); |
51 | 0 | return; |
52 | 0 | case 64: |
53 | 0 | CDEF_RECT_CW(64); |
54 | 0 | return; |
55 | 0 | case 66: |
56 | 0 | CDEF_RECT_CW(66); |
57 | 0 | return; |
58 | 0 | case 68: |
59 | 0 | CDEF_RECT_CW(68); |
60 | 0 | return; |
61 | 0 | default: |
62 | 0 | break; |
63 | 0 | } |
64 | 0 | #undef CDEF_RECT_CW |
65 | 0 | // Other widths are legitimate when the coded frame width is not a multiple of the CDEF block |
66 | 0 | // size (e.g. reference scaling / --resize-mode produces partial right-edge filter blocks). |
67 | 0 | // The fast cases above cover the common geometries; any other width uses this variable-width |
68 | 0 | // memcpy fallback. |
69 | 0 | for (int r = 0; r < v; r++) { |
70 | 0 | memcpy(dst, base, (size_t)h); |
71 | 0 | dst += dstride; |
72 | 0 | base += sstride; |
73 | 0 | } |
74 | 0 | } Unexecuted instantiation: cdef_process.c:svt_cdef_copy_rect8 Unexecuted instantiation: enc_cdef.c:svt_cdef_copy_rect8 |
75 | | |
76 | | // HBD-only paths below (compiled out of RTC via the CDEF_8BITS_PATH guards at the call sites). |
77 | | |
78 | | // uint16->uint16 rect copy (edge-path src assembly). |
79 | 0 | static inline void svt_aom_copy_rect(uint16_t* dst, int dstride, const uint16_t* src, int sstride, int v, int h) { |
80 | 0 | for (int r = 0; r < v; r++) { |
81 | 0 | memcpy(dst, src, sizeof(*dst) * (size_t)h); |
82 | 0 | dst += dstride; |
83 | 0 | src += sstride; |
84 | 0 | } |
85 | 0 | } Unexecuted instantiation: cdef_process.c:svt_aom_copy_rect Unexecuted instantiation: enc_cdef.c:svt_aom_copy_rect |
86 | | |
87 | | // uint16 rect fill (edge-path off-frame sentinel). |
88 | 0 | static inline void svt_aom_fill_rect(uint16_t* dst, int dstride, int v, int h, uint16_t x) { |
89 | 0 | for (int r = 0; r < v; r++) { |
90 | 0 | svt_aom_memset16(dst + r * dstride, x, (size_t)h); |
91 | 0 | } |
92 | 0 | } Unexecuted instantiation: cdef_process.c:svt_aom_fill_rect Unexecuted instantiation: enc_cdef.c:svt_aom_fill_rect |
93 | | |
94 | | // CDEF superblock copy into the padded src buffer: widen 8-bit recon (u8->u16), or copy 16-bit recon |
95 | | // (u16->u16), from a (voffset,hoffset) origin. Composes the primitives above. |
96 | | static inline void svt_aom_copy_sb8_16(uint16_t* dst, int dstride, const uint8_t* src, int src_voffset, int src_hoffset, |
97 | 0 | int sstride, int vsize, int hsize, int is_16bit) { |
98 | 0 | if (is_16bit) { |
99 | 0 | svt_aom_copy_rect( |
100 | 0 | dst, dstride, (const uint16_t*)src + (src_voffset * sstride + src_hoffset), sstride, vsize, hsize); |
101 | 0 | } else { |
102 | 0 | svt_aom_copy_rect8_8bit_to_16bit( |
103 | 0 | dst, dstride, &src[src_voffset * sstride + src_hoffset], sstride, vsize, hsize); |
104 | 0 | } |
105 | 0 | } Unexecuted instantiation: cdef_process.c:svt_aom_copy_sb8_16 Unexecuted instantiation: enc_cdef.c:svt_aom_copy_sb8_16 |
106 | | |
107 | | #endif // EbCdefCopy_h |