summaryrefslogtreecommitdiff
path: root/src/i965_vpp_avs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/i965_vpp_avs.c')
-rw-r--r--src/i965_vpp_avs.c271
1 files changed, 0 insertions, 271 deletions
diff --git a/src/i965_vpp_avs.c b/src/i965_vpp_avs.c
deleted file mode 100644
index 58d0949..0000000
--- a/src/i965_vpp_avs.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * i965_vpp_avs.c - Adaptive Video Scaler (AVS) block
- *
- * Copyright (C) 2014 Intel Corporation
- * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "sysdeps.h"
-#include <math.h>
-#include <va/va.h>
-#include "i965_vpp_avs.h"
-
-typedef void (*AVSGenCoeffsFunc)(float *coeffs, int num_coeffs, int phase,
- int num_phases, float f);
-
-/* Initializes all coefficients to zero */
-static void
-avs_init_coeffs(float *coeffs, int num_coeffs)
-{
-#if defined(__STDC_IEC_559__) && (__STDC_IEC_559__ > 0)
- memset(coeffs, 0, num_coeffs * sizeof(*coeffs));
-#else
- int i;
-
- for (i = 0; i < num_coeffs; i++)
- coeffs[i] = 0.0f;
-#endif
-}
-
-/* Computes the sinc(x) function */
-static float
-avs_sinc(float x)
-{
- if (x == 0.0f)
- return 1.0f;
- return sin(x * M_PI) / (x * M_PI);
-}
-
-/* Convolution kernel for linear interpolation */
-static float
-avs_kernel_linear(float x)
-{
- const float abs_x = fabsf(x);
-
- return abs_x < 1.0f ? 1 - abs_x : 0.0f;
-}
-
-/* Convolution kernel for Lanczos-based interpolation */
-static float
-avs_kernel_lanczos(float x, float a)
-{
- const float abs_x = fabsf(x);
-
- return abs_x < a ? avs_sinc(x) * avs_sinc(x / a) : 0.0f;
-}
-
-/* Truncates floating-point value towards an epsilon factor */
-static inline float
-avs_trunc_coeff(float x, float epsilon)
-{
- return rintf(x / epsilon) * epsilon;
-}
-
-/* Normalize coefficients for one sample/direction */
-static void
-avs_normalize_coeffs_1(float *coeffs, int num_coeffs, float epsilon)
-{
- float s, sum = 0.0;
- int i, c, r, r1;
-
- for (i = 0; i < num_coeffs; i++)
- sum += coeffs[i];
-
- if (sum < epsilon)
- return;
-
- s = 0.0;
- for (i = 0; i < num_coeffs; i++)
- s += (coeffs[i] = avs_trunc_coeff(coeffs[i] / sum, epsilon));
-
- /* Distribute the remaining bits, while allocating more to the center */
- c = num_coeffs/2;
- c = c - (coeffs[c - 1] > coeffs[c]);
-
- r = (1.0f - s) / epsilon;
- r1 = r / 4;
- if (coeffs[c + 1] == 0.0f)
- coeffs[c] += r * epsilon;
- else {
- coeffs[c] += (r - 2*r1) * epsilon;
- coeffs[c - 1] += r1 * epsilon;
- coeffs[c + 1] += r1 * epsilon;
- }
-}
-
-/* Normalize all coefficients so that their sum yields 1.0f */
-static void
-avs_normalize_coeffs(AVSCoeffs *coeffs, const AVSConfig *config)
-{
- avs_normalize_coeffs_1(coeffs->y_k_h, config->num_luma_coeffs,
- config->coeff_epsilon);
- avs_normalize_coeffs_1(coeffs->y_k_v, config->num_luma_coeffs,
- config->coeff_epsilon);
- avs_normalize_coeffs_1(coeffs->uv_k_h, config->num_chroma_coeffs,
- config->coeff_epsilon);
- avs_normalize_coeffs_1(coeffs->uv_k_v, config->num_chroma_coeffs,
- config->coeff_epsilon);
-}
-
-/* Validate coefficients for one sample/direction */
-static bool
-avs_validate_coeffs_1(float *coeffs, int num_coeffs, const float *min_coeffs,
- const float *max_coeffs)
-{
- int i;
-
- for (i = 0; i < num_coeffs; i++) {
- if (coeffs[i] < min_coeffs[i] || coeffs[i] > max_coeffs[i])
- return false;
- }
- return true;
-}
-
-/* Validate coefficients wrt. the supplied range in config */
-static bool
-avs_validate_coeffs(AVSCoeffs *coeffs, const AVSConfig *config)
-{
- const AVSCoeffs * const min_coeffs = &config->coeff_range.lower_bound;
- const AVSCoeffs * const max_coeffs = &config->coeff_range.upper_bound;
-
- return avs_validate_coeffs_1(coeffs->y_k_h, config->num_luma_coeffs,
- min_coeffs->y_k_h, max_coeffs->y_k_h) &&
- avs_validate_coeffs_1(coeffs->y_k_v, config->num_luma_coeffs,
- min_coeffs->y_k_v, max_coeffs->y_k_v) &&
- avs_validate_coeffs_1(coeffs->uv_k_h, config->num_chroma_coeffs,
- min_coeffs->uv_k_h, max_coeffs->uv_k_h) &&
- avs_validate_coeffs_1(coeffs->uv_k_v, config->num_chroma_coeffs,
- min_coeffs->uv_k_v, max_coeffs->uv_k_v);
-}
-
-/* Generate coefficients for default quality (bilinear) */
-static void
-avs_gen_coeffs_linear(float *coeffs, int num_coeffs, int phase, int num_phases,
- float f)
-{
- const int c = num_coeffs/2 - 1;
- const float p = (float)phase / (num_phases*2);
-
- avs_init_coeffs(coeffs, num_coeffs);
- coeffs[c] = avs_kernel_linear(p);
- coeffs[c + 1] = avs_kernel_linear(p - 1);
-}
-
-/* Generate coefficients for high quality (lanczos) */
-static void
-avs_gen_coeffs_lanczos(float *coeffs, int num_coeffs, int phase, int num_phases,
- float f)
-{
- const int c = num_coeffs/2 - 1;
- const int l = num_coeffs > 4 ? 3 : 2;
- const float p = (float)phase / (num_phases*2);
- int i;
-
- if (f > 1.0f)
- f = 1.0f;
- for (i = 0; i < num_coeffs; i++)
- coeffs[i] = avs_kernel_lanczos((i - (c + p)) * f, l);
-}
-
-/* Generate coefficients with the supplied scaler */
-static bool
-avs_gen_coeffs(AVSState *avs, float sx, float sy, AVSGenCoeffsFunc gen_coeffs)
-{
- const AVSConfig * const config = avs->config;
- int i;
-
- for (i = 0; i <= config->num_phases; i++) {
- AVSCoeffs * const coeffs = &avs->coeffs[i];
-
- gen_coeffs(coeffs->y_k_h, config->num_luma_coeffs,
- i, config->num_phases, sx);
- gen_coeffs(coeffs->uv_k_h, config->num_chroma_coeffs,
- i, config->num_phases, sx);
- gen_coeffs(coeffs->y_k_v, config->num_luma_coeffs,
- i, config->num_phases, sy);
- gen_coeffs(coeffs->uv_k_v, config->num_chroma_coeffs,
- i, config->num_phases, sy);
-
- avs_normalize_coeffs(coeffs, config);
- if (!avs_validate_coeffs(coeffs, config))
- return false;
- }
- return true;
-}
-
-/* Initializes AVS state with the supplied configuration */
-void
-avs_init_state(AVSState *avs, const AVSConfig *config)
-{
- avs->config = config;
- avs->flags = 0;
- avs->scale_x = 0.0f;
- avs->scale_y = 0.0f;
-}
-
-/* Checks whether the AVS scaling parameters changed */
-static inline bool
-avs_params_changed(AVSState *avs, float sx, float sy, uint32_t flags)
-{
- if (avs->flags != flags)
- return true;
-
- if (flags >= VA_FILTER_SCALING_HQ) {
- if (avs->scale_x != sx || avs->scale_y != sy)
- return true;
- }
- else {
- if (avs->scale_x == 0.0f || avs->scale_y == 0.0f)
- return true;
- }
- return false;
-}
-
-/* Updates AVS coefficients for the supplied factors and quality level */
-bool
-avs_update_coefficients(AVSState *avs, float sx, float sy, uint32_t flags)
-{
- AVSGenCoeffsFunc gen_coeffs;
-
- flags &= VA_FILTER_SCALING_MASK;
- if (!avs_params_changed(avs, sx, sy, flags))
- return true;
-
- switch (flags) {
- case VA_FILTER_SCALING_HQ:
- gen_coeffs = avs_gen_coeffs_lanczos;
- break;
- default:
- gen_coeffs = avs_gen_coeffs_linear;
- break;
- }
- if (!avs_gen_coeffs(avs, sx, sy, gen_coeffs)) {
- assert(0 && "invalid set of coefficients generated");
- return false;
- }
-
- avs->flags = flags;
- avs->scale_x = sx;
- avs->scale_y = sy;
- return true;
-}