/
githubmirror
/
FFmpeg
Обзор
Документация
Войти
/
githubmirror
/
FFmpeg
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
libswscale/ops_chain.c
215 строк
6 KB
Andreas Rheinhardt
swscale/ops_chain: Disable ff_sws_setup_{clear,clamp,scale}
01 июл 2026, 06:03
01 июл 2026, 06:03
66d9b8e
Код
Авторство
О чём код?
/** * Copyright (C) 2025 Niklas Haas * * 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/avassert.h" #include "libavutil/mem.h" #include "libavutil/rational.h" #include "ops_chain.h" SwsOpChain *ff_sws_op_chain_alloc(void) { return av_mallocz(sizeof(SwsOpChain)); } void ff_sws_op_chain_free_cb(void *ptr) { if (!ptr) return; SwsOpChain *chain = ptr; for (int i = 0; i < chain->num_impl + 1; i++) { if (chain->free[i]) chain->free[i](&chain->impl[i].priv); } av_free(chain); } int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr func, void (*free)(SwsOpPriv *), const SwsOpPriv *priv) { const int idx = chain->num_impl; if (idx == SWS_MAX_OPS) return AVERROR(EINVAL); av_assert1(func); chain->impl[idx].cont = func; chain->impl[idx + 1].priv = *priv; chain->free[idx + 1] = free; chain->num_impl++; return 0; } #define q2pixel(type, q) ((q).den ? (type) (q).num / (q).den : 0) #if ARCH_AARCH64 int ff_sws_setup_scale(const SwsImplParams *params, SwsImplResult *out) { const SwsOp *op = params->op; const AVRational64 factor = op->scale.factor; switch (op->type) { case SWS_PIXEL_U8: out->priv.u8[0] = q2pixel(uint8_t, factor); break; case SWS_PIXEL_U16: out->priv.u16[0] = q2pixel(uint16_t, factor); break; case SWS_PIXEL_U32: out->priv.u32[0] = q2pixel(uint32_t, factor); break; case SWS_PIXEL_F32: out->priv.f32[0] = q2pixel(float, factor); break; default: return AVERROR(EINVAL); } return 0; } int ff_sws_setup_clamp(const SwsImplParams *params, SwsImplResult *out) { const SwsOp *op = params->op; for (int i = 0; i < 4; i++) { const AVRational64 limit = op->clamp.limit[i]; switch (op->type) { case SWS_PIXEL_U8: out->priv.u8[i] = q2pixel(uint8_t, limit); break; case SWS_PIXEL_U16: out->priv.u16[i] = q2pixel(uint16_t, limit); break; case SWS_PIXEL_U32: out->priv.u32[i] = q2pixel(uint32_t, limit); break; case SWS_PIXEL_F32: out->priv.f32[i] = q2pixel(float, limit); break; default: return AVERROR(EINVAL); } } return 0; } int ff_sws_setup_clear(const SwsImplParams *params, SwsImplResult *out) { const SwsOp *op = params->op; for (int i = 0; i < 4; i++) { const AVRational64 value = op->clear.value[i]; if (!value.den) continue; switch (op->type) { case SWS_PIXEL_U8: out->priv.u8[i] = q2pixel(uint8_t, value); break; case SWS_PIXEL_U16: out->priv.u16[i] = q2pixel(uint16_t, value); break; case SWS_PIXEL_U32: out->priv.u32[i] = q2pixel(uint32_t, value); break; case SWS_PIXEL_F32: out->priv.f32[i] = q2pixel(float, value); break; default: return AVERROR(EINVAL); } } return 0; } #endif int ff_sws_uop_lookup(SwsContext *ctx, const SwsUOpTable *const tables[], int num_tables, const SwsUOp *uop, const int block_size, SwsOpChain *chain) { const unsigned cpu_flags = av_get_cpu_flags(); const SwsUOpEntry *match = NULL; int ret; SwsImplParams params = { .ctx = ctx, .uop = uop }; for (int n = 0; !match && n < num_tables; n++) { const SwsUOpTable *table = params.table = tables[n]; if (table->block_size && table->block_size != block_size || table->cpu_flags & ~cpu_flags) continue; for (int i = 0; table->entries[i]; i++) { const SwsUOpEntry *entry = table->entries[i]; const SwsUOp entry_uop = { .uop = entry->uop, .type = entry->type, .mask = entry->mask, .par = entry->par, }; if (ff_sws_uop_cmp(uop, &entry_uop) != 0) continue; if (entry->check && !entry->check(¶ms)) continue; match = entry; break; } } if (!match) { char name[64]; ff_sws_uop_name(uop, name); av_log(ctx, AV_LOG_DEBUG, "No implementation found for: %s\n", name); return AVERROR(ENOTSUP); } SwsImplResult res = {0}; if (match->setup) { ret = match->setup(¶ms, &res); if (ret < 0) return ret; } ret = ff_sws_op_chain_append(chain, res.func ? res.func : match->func, res.free, &res.priv); if (ret < 0) { if (res.free) res.free(&res.priv); return ret; } for (int i = 0; i < 4; i++) { chain->over_read[i] = FFMAX(chain->over_read[i], res.over_read[i]); chain->over_write[i] = FFMAX(chain->over_write[i], res.over_write[i]); } chain->cpu_flags |= params.table->cpu_flags; return 0; } int ff_sws_setup_scalar(const SwsImplParams *params, SwsImplResult *out) { const SwsUOp *uop = params->uop; const SwsPixel scalar = uop->data.scalar; switch (uop->type) { case SWS_PIXEL_U8: out->priv.u8[0] = scalar.u8; break; case SWS_PIXEL_U16: out->priv.u16[0] = scalar.u16; break; case SWS_PIXEL_U32: out->priv.u32[0] = scalar.u32; break; case SWS_PIXEL_F32: out->priv.f32[0] = scalar.f32; break; default: return AVERROR(EINVAL); } return 0; } int ff_sws_setup_vec4(const SwsImplParams *params, SwsImplResult *out) { const SwsUOp *uop = params->uop; for (int i = 0; i < 4; i++) { const SwsPixel vi = uop->data.vec4[i]; switch (uop->type) { case SWS_PIXEL_U8: out->priv.u8[i] = vi.u8; break; case SWS_PIXEL_U16: out->priv.u16[i] = vi.u16; break; case SWS_PIXEL_U32: out->priv.u32[i] = vi.u32; break; case SWS_PIXEL_F32: out->priv.f32[i] = vi.f32; break; default: return AVERROR(EINVAL); } } return 0; }