OSDN Git Service

vpp: factor out calculation of AVS coefficients.
[android-x86/hardware-intel-common-vaapi.git] / src / i965_vpp_avs.c
1 /*
2  * i965_vpp_avs.c - Adaptive Video Scaler (AVS) block
3  *
4  * Copyright (C) 2014 Intel Corporation
5  *   Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
6  *
7  * The source code contained or described herein and all documents related to
8  * the source code ("Material") are owned by Intel Corporation or its suppliers
9  * or licensors. Title to the Material remains with Intel Corporation or its
10  * suppliers and licensors. The Material contains trade secrets and proprietary
11  * and confidential information of Intel or its suppliers and licensors. The
12  * Material is protected by worldwide copyright and trade secret laws and
13  * treaty provisions. No part of the Material may be used, copied, reproduced,
14  * modified, published, uploaded, posted, transmitted, distributed, or
15  * disclosed in any way without Intel's prior express written permission.
16  *
17  * No license under any patent, copyright, trade secret or other intellectual
18  * property right is granted to or conferred upon you by disclosure or delivery
19  * of the Materials, either expressly, by implication, inducement, estoppel or
20  * otherwise. Any license under such intellectual property rights must be
21  * express and approved by Intel in writing.
22  */
23
24 #include "sysdeps.h"
25 #include <math.h>
26 #include <va/va.h>
27 #include "i965_vpp_avs.h"
28
29 typedef void (*AVSGenCoeffsFunc)(float *coeffs, int num_coeffs, int phase,
30     int num_phases, float f);
31
32 /* Initializes all coefficients to zero */
33 static void
34 avs_init_coeffs(float *coeffs, int num_coeffs)
35 {
36 #if defined(__STDC_IEC_559__) && (__STDC_IEC_559__ > 0)
37     memset(coeffs, 0, num_coeffs * sizeof(*coeffs));
38 #else
39     int i;
40
41     for (i = 0; i < num_coeffs; i++)
42         coeffs[i] = 0.0f;
43 #endif
44 }
45
46 /* Convolution kernel for linear interpolation */
47 static float
48 avs_kernel_linear(float x)
49 {
50     const float abs_x = fabsf(x);
51
52     return abs_x < 1.0f ? 1 - abs_x : 0.0f;
53 }
54
55 /* Generate coefficients for default quality (bilinear) */
56 static void
57 avs_gen_coeffs_linear(float *coeffs, int num_coeffs, int phase, int num_phases,
58     float f)
59 {
60     const int c = num_coeffs/2 - 1;
61     const float p = (float)phase / (num_phases*2);
62
63     avs_init_coeffs(coeffs, num_coeffs);
64     coeffs[c] = avs_kernel_linear(p);
65     coeffs[c + 1] = avs_kernel_linear(p - 1);
66 }
67
68 /* Generate coefficients with the supplied scaler */
69 static void
70 avs_gen_coeffs(AVSState *avs, float sx, float sy, AVSGenCoeffsFunc gen_coeffs)
71 {
72     const AVSConfig * const config = avs->config;
73     int i;
74
75     for (i = 0; i <= config->num_phases; i++) {
76         AVSCoeffs * const coeffs = &avs->coeffs[i];
77
78         gen_coeffs(coeffs->y_k_h, config->num_luma_coeffs,
79             i, config->num_phases, sx);
80         gen_coeffs(coeffs->uv_k_h, config->num_chroma_coeffs,
81             i, config->num_phases, sx);
82         gen_coeffs(coeffs->y_k_v, config->num_luma_coeffs,
83             i, config->num_phases, sy);
84         gen_coeffs(coeffs->uv_k_v, config->num_chroma_coeffs,
85             i, config->num_phases, sy);
86     }
87 }
88
89 /* Initializes AVS state with the supplied configuration */
90 void
91 avs_init_state(AVSState *avs, const AVSConfig *config)
92 {
93     avs->config = config;
94 }
95
96 /* Updates AVS coefficients for the supplied factors and quality level */
97 bool
98 avs_update_coefficients(AVSState *avs, float sx, float sy, uint32_t flags)
99 {
100     AVSGenCoeffsFunc gen_coeffs;
101
102     flags &= VA_FILTER_SCALING_MASK;
103     switch (flags) {
104     default:
105         gen_coeffs = avs_gen_coeffs_linear;
106         break;
107     }
108     avs_gen_coeffs(avs, sx, sy, gen_coeffs);
109     return true;
110 }