Coverage Report

Created: 2026-03-12 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libswscale/ops_chain.h
Line
Count
Source
1
/**
2
 * Copyright (C) 2025 Niklas Haas
3
 *
4
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * FFmpeg is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with FFmpeg; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
21
#ifndef SWSCALE_OPS_CHAIN_H
22
#define SWSCALE_OPS_CHAIN_H
23
24
#include "libavutil/cpu.h"
25
26
#include "ops_internal.h"
27
28
/**
29
 * Helpers for SIMD implementations based on chained kernels, using a
30
 * continuation passing style to link them together.
31
 *
32
 * The basic idea here is to "link" together a series of different operation
33
 * kernels by constructing a list of kernel addresses into an SwsOpChain. Each
34
 * kernel will load the address of the next kernel (the "continuation") from
35
 * this struct, and jump directly into it; using an internal function signature
36
 * that is an implementation detail of the specific backend.
37
 */
38
39
/**
40
 * Private data for each kernel.
41
 */
42
typedef union SwsOpPriv {
43
    DECLARE_ALIGNED_16(char, data)[16];
44
45
    /* Common types */
46
    void *ptr;
47
    int8_t    i8[16];
48
    uint8_t   u8[16];
49
    uint16_t u16[8];
50
    int16_t  i16[8];
51
    uint32_t u32[4];
52
    float    f32[4];
53
} SwsOpPriv;
54
55
static_assert(sizeof(SwsOpPriv) == 16, "SwsOpPriv size mismatch");
56
57
/* Setup helpers */
58
int ff_sws_setup_u(const SwsOp *op, SwsOpPriv *out);
59
int ff_sws_setup_u8(const SwsOp *op, SwsOpPriv *out);
60
int ff_sws_setup_q(const SwsOp *op, SwsOpPriv *out);
61
int ff_sws_setup_q4(const SwsOp *op, SwsOpPriv *out);
62
63
/**
64
 * Per-kernel execution context.
65
 *
66
 * Note: This struct is hard-coded in assembly, so do not change the layout.
67
 */
68
typedef void (*SwsFuncPtr)(void);
69
typedef struct SwsOpImpl {
70
    SwsFuncPtr cont; /* [offset =  0] Continuation for this operation. */
71
    SwsOpPriv  priv; /* [offset = 16] Private data for this operation. */
72
} SwsOpImpl;
73
74
static_assert(sizeof(SwsOpImpl) == 32,         "SwsOpImpl layout mismatch");
75
static_assert(offsetof(SwsOpImpl, priv) == 16, "SwsOpImpl layout mismatch");
76
77
/**
78
 * Compiled "chain" of operations, which can be dispatched efficiently.
79
 * Effectively just a list of function pointers, alongside a small amount of
80
 * private data for each operation.
81
 */
82
typedef struct SwsOpChain {
83
0
#define SWS_MAX_OPS 16
84
    SwsOpImpl impl[SWS_MAX_OPS + 1]; /* reserve extra space for the entrypoint */
85
    void (*free[SWS_MAX_OPS + 1])(void *);
86
    int num_impl;
87
    int cpu_flags; /* set of all used CPU flags */
88
} SwsOpChain;
89
90
SwsOpChain *ff_sws_op_chain_alloc(void);
91
void ff_sws_op_chain_free_cb(void *chain);
92
static inline void ff_sws_op_chain_free(SwsOpChain *chain)
93
0
{
94
0
    ff_sws_op_chain_free_cb(chain);
95
0
}
Unexecuted instantiation: ops_backend.c:ff_sws_op_chain_free
Unexecuted instantiation: ops_chain.c:ff_sws_op_chain_free
Unexecuted instantiation: ops_memcpy.c:ff_sws_op_chain_free
96
97
/* Returns 0 on success, or a negative error code. */
98
int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr func,
99
                           void (*free)(void *), const SwsOpPriv *priv);
100
101
typedef struct SwsOpEntry {
102
    /* Kernel metadata; reduced size subset of SwsOp */
103
    SwsOpType op;
104
    SwsPixelType type;
105
    bool flexible; /* if true, only the type and op are matched */
106
    bool unused[4]; /* for kernels which operate on a subset of components */
107
108
    union { /* extra data defining the operation, unless `flexible` is true */
109
        SwsReadWriteOp rw;
110
        SwsPackOp      pack;
111
        SwsSwizzleOp   swizzle;
112
        SwsConvertOp   convert;
113
        uint32_t       linear_mask; /* subset of SwsLinearOp */
114
        int            dither_size; /* subset of SwsDitherOp */
115
        int            clear_value; /* clear value for integer clears */
116
        AVRational     scale;       /* scale factor for SWS_OP_SCALE */
117
    };
118
119
    /* Kernel implementation */
120
    SwsFuncPtr func;
121
    int (*setup)(const SwsOp *op, SwsOpPriv *out); /* optional */
122
    void (*free)(void *priv);
123
} SwsOpEntry;
124
125
typedef struct SwsOpTable {
126
    unsigned cpu_flags;   /* required CPU flags for this table */
127
    int block_size;       /* fixed block size of this table */
128
    const SwsOpEntry *entries[]; /* terminated by NULL */
129
} SwsOpTable;
130
131
/**
132
 * "Compile" a single op by looking it up in a list of fixed size op tables.
133
 * See `op_match` in `ops_chain.c` for details on how the matching works.
134
 *
135
 * Returns 0, AVERROR(EAGAIN), or a negative error code.
136
 */
137
int ff_sws_op_compile_tables(const SwsOpTable *const tables[], int num_tables,
138
                             SwsOpList *ops, const int block_size,
139
                             SwsOpChain *chain);
140
141
#endif