FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswscale/ops_chain.c
Date: 2026-10-30 17:37:53
Exec Total Coverage
Lines: 72 80 90.0%
Functions: 6 6 100.0%
Branches: 42 52 80.8%

Line Branch Exec 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 #include "libavutil/avassert.h"
22 #include "libavutil/mem.h"
23
24 #include "ops_chain.h"
25
26 290568 SwsOpChain *ff_sws_op_chain_alloc(void)
27 {
28 290568 return av_mallocz(sizeof(SwsOpChain));
29 }
30
31 290568 void ff_sws_op_chain_free_cb(void *ptr)
32 {
33
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 290568 times.
290568 if (!ptr)
34 ✗ return;
35
36 290568 SwsOpChain *chain = ptr;
37
2/2
✓ Branch 0 taken 1694451 times.
✓ Branch 1 taken 290568 times.
1985019 for (int i = 0; i < chain->num_impl + 1; i++) {
38
2/2
✓ Branch 0 taken 323027 times.
✓ Branch 1 taken 1371424 times.
1694451 if (chain->free[i])
39 323027 chain->free[i](&chain->impl[i].priv);
40 }
41
42 290568 av_free(chain);
43 }
44
45 1403883 int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr func,
46 void (*free)(SwsOpPriv *), const SwsOpPriv *priv)
47 {
48 1403883 const int idx = chain->num_impl;
49
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1403883 times.
1403883 if (idx == SWS_MAX_OPS)
50 ✗ return AVERROR(EINVAL);
51
52 av_assert1(func);
53 1403883 chain->impl[idx].cont = func;
54 1403883 chain->impl[idx + 1].priv = *priv;
55 1403883 chain->free[idx + 1] = free;
56 1403883 chain->num_impl++;
57 1403883 return 0;
58 }
59
60 1420243 int ff_sws_uop_lookup(SwsContext *ctx, const SwsUOpTable *const tables[],
61 int num_tables, const SwsUOp *uop, const int block_size,
62 SwsOpChain *chain)
63 {
64 1420243 const unsigned cpu_flags = av_get_cpu_flags();
65 1420243 const SwsUOpEntry *match = NULL;
66 int ret;
67
68 1420243 SwsImplParams params = {
69 .ctx = ctx,
70 .uop = uop
71 };
72
73
4/4
✓ Branch 0 taken 5119179 times.
✓ Branch 1 taken 1403883 times.
✓ Branch 2 taken 5102819 times.
✓ Branch 3 taken 16360 times.
6523062 for (int n = 0; !match && n < num_tables; n++) {
74 5102819 const SwsUOpTable *table = params.table = tables[n];
75
3/4
✓ Branch 0 taken 5102819 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2748211 times.
✓ Branch 3 taken 2354608 times.
5102819 if (table->block_size && table->block_size != block_size ||
76
2/2
✓ Branch 0 taken 4542 times.
✓ Branch 1 taken 2743669 times.
2748211 table->cpu_flags & ~cpu_flags)
77 2359150 continue;
78
79
2/2
✓ Branch 0 taken 295790802 times.
✓ Branch 1 taken 1339786 times.
297130588 for (int i = 0; table->entries[i]; i++) {
80 295790802 const SwsUOpEntry *entry = table->entries[i];
81 295790802 const SwsUOp entry_uop = {
82 295790802 .uop = entry->uop,
83 295790802 .type = entry->type,
84 295790802 .mask = entry->mask,
85 .par = entry->par,
86 };
87
88
2/2
✓ Branch 1 taken 294381588 times.
✓ Branch 2 taken 1409214 times.
295790802 if (ff_sws_uop_cmp(uop, &entry_uop) != 0)
89 294386919 continue;
90
4/4
✓ Branch 0 taken 38215 times.
✓ Branch 1 taken 1370999 times.
✓ Branch 3 taken 5331 times.
✓ Branch 4 taken 32884 times.
1409214 if (entry->check && !entry->check(&params))
91 5331 continue;
92
93 1403883 match = entry;
94 1403883 break;
95 }
96 }
97
98
2/2
✓ Branch 0 taken 16360 times.
✓ Branch 1 taken 1403883 times.
1420243 if (!match) {
99 char name[64];
100 16360 ff_sws_uop_name(uop, name);
101 16360 av_log(ctx, AV_LOG_DEBUG, "No implementation found for: %s\n", name);
102 16360 return AVERROR(ENOTSUP);
103 }
104
105 1403883 SwsImplResult res = {0};
106
2/2
✓ Branch 0 taken 622356 times.
✓ Branch 1 taken 781527 times.
1403883 if (match->setup) {
107 622356 ret = match->setup(&params, &res);
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 622356 times.
622356 if (ret < 0)
109 ✗ return ret;
110 }
111
112
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1403883 times.
1403883 ret = ff_sws_op_chain_append(chain, res.func ? res.func : match->func,
113 res.free, &res.priv);
114
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1403883 times.
1403883 if (ret < 0) {
115 ✗ if (res.free)
116 ✗ res.free(&res.priv);
117 ✗ return ret;
118 }
119
120
2/2
✓ Branch 0 taken 5615532 times.
✓ Branch 1 taken 1403883 times.
7019415 for (int i = 0; i < 4; i++) {
121 5615532 chain->over_read[i] = FFMAX(chain->over_read[i], res.over_read[i]);
122 5615532 chain->over_write[i] = FFMAX(chain->over_write[i], res.over_write[i]);
123 }
124
125 1403883 chain->cpu_flags |= params.table->cpu_flags;
126 1403883 return 0;
127 }
128
129 20901 int ff_sws_setup_scalar(const SwsImplParams *params, SwsImplResult *out)
130 {
131 20901 const SwsUOp *uop = params->uop;
132 20901 const SwsPixel scalar = uop->data.scalar;
133
4/5
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 276 times.
✓ Branch 2 taken 57 times.
✓ Branch 3 taken 20491 times.
✗ Branch 4 not taken.
20901 switch (uop->type) {
134 77 case SWS_PIXEL_U8: out->priv.u8[0] = scalar.u8; break;
135 276 case SWS_PIXEL_U16: out->priv.u16[0] = scalar.u16; break;
136 57 case SWS_PIXEL_U32: out->priv.u32[0] = scalar.u32; break;
137 20491 case SWS_PIXEL_F32: out->priv.f32[0] = scalar.f32; break;
138 ✗ default: return AVERROR(EINVAL);
139 }
140
141 20901 return 0;
142 }
143
144 207619 int ff_sws_setup_vec4(const SwsImplParams *params, SwsImplResult *out)
145 {
146 207619 const SwsUOp *uop = params->uop;
147
2/2
✓ Branch 0 taken 830476 times.
✓ Branch 1 taken 207619 times.
1038095 for (int i = 0; i < 4; i++) {
148 830476 const SwsPixel vi = uop->data.vec4[i];
149
4/5
✓ Branch 0 taken 26804 times.
✓ Branch 1 taken 47736 times.
✓ Branch 2 taken 20308 times.
✓ Branch 3 taken 735628 times.
✗ Branch 4 not taken.
830476 switch (uop->type) {
150 26804 case SWS_PIXEL_U8: out->priv.u8[i] = vi.u8; break;
151 47736 case SWS_PIXEL_U16: out->priv.u16[i] = vi.u16; break;
152 20308 case SWS_PIXEL_U32: out->priv.u32[i] = vi.u32; break;
153 735628 case SWS_PIXEL_F32: out->priv.f32[i] = vi.f32; break;
154 ✗ default: return AVERROR(EINVAL);
155 }
156 }
157
158 207619 return 0;
159 }
160