OSDN Git Service

Fix a typo
[android-x86/hardware-intel-common-vaapi.git] / src / intel_common_vpp_internal.c
1 /*
2  * Copyright © 2016 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <assert.h>
30
31 #include "intel_batchbuffer.h"
32 #include "intel_driver.h"
33 #include "i965_drv_video.h"
34 #include "i965_post_processing.h"
35 #include "gen75_picture_process.h"
36
37 #include "intel_gen_vppapi.h"
38 #include "intel_common_vpp_internal.h"
39
40 static VAStatus
41 intel_yuv420p8_scaling_post_processing(
42     VADriverContextP   ctx,
43     struct i965_post_processing_context *pp_context,
44     struct i965_surface *src_surface,
45     VARectangle *src_rect,
46     struct i965_surface *dst_surface,
47     VARectangle *dst_rect)
48 {
49     struct i965_driver_data *i965 = i965_driver_data(ctx);
50     VAStatus va_status;
51
52     if (IS_GEN8(i965->intel.device_info))
53         va_status = gen8_yuv420p8_scaling_post_processing(ctx, pp_context,
54                                                           src_surface,
55                                                           src_rect,
56                                                           dst_surface,
57                                                           dst_rect);
58     else
59         va_status = gen9_yuv420p8_scaling_post_processing(ctx, pp_context,
60                                                           src_surface,
61                                                           src_rect,
62                                                           dst_surface,
63                                                           dst_rect);
64
65     return va_status;
66 }
67
68 static VAStatus
69 intel_10bit_8bit_scaling_post_processing(VADriverContextP   ctx,
70                                          struct i965_post_processing_context *pp_context,
71                                          struct i965_surface *src_surface,
72                                          VARectangle *src_rect,
73                                          struct i965_surface *dst_surface,
74                                          VARectangle *dst_rect)
75 {
76     struct i965_driver_data *i965 = i965_driver_data(ctx);
77     VAStatus va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
78
79     if (IS_GEN9(i965->intel.device_info) ||
80         IS_GEN10(i965->intel.device_info))
81         va_status = gen9_10bit_8bit_scaling_post_processing(ctx, pp_context,
82                                                             src_surface,
83                                                             src_rect,
84                                                             dst_surface,
85                                                             dst_rect);
86
87     return va_status;
88 }
89
90 static VAStatus
91 intel_8bit_420_rgb32_scaling_post_processing(VADriverContextP   ctx,
92                                              struct i965_post_processing_context *pp_context,
93                                              struct i965_surface *src_surface,
94                                              VARectangle *src_rect,
95                                              struct i965_surface *dst_surface,
96                                              VARectangle *dst_rect)
97 {
98     struct i965_driver_data *i965 = i965_driver_data(ctx);
99     VAStatus va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
100
101     if (IS_GEN8(i965->intel.device_info))
102         va_status = gen8_8bit_420_rgb32_scaling_post_processing(ctx, pp_context,
103                                                                 src_surface,
104                                                                 src_rect,
105                                                                 dst_surface,
106                                                                 dst_rect);
107     else
108         va_status = gen9_8bit_420_rgb32_scaling_post_processing(ctx, pp_context,
109                                                                 src_surface,
110                                                                 src_rect,
111                                                                 dst_surface,
112                                                                 dst_rect);
113
114     return va_status;
115 }
116
117 VAStatus
118 intel_common_scaling_post_processing(VADriverContextP ctx,
119                                      struct i965_post_processing_context *pp_context,
120                                      const struct i965_surface *src_surface,
121                                      const VARectangle *src_rect,
122                                      struct i965_surface *dst_surface,
123                                      const VARectangle *dst_rect)
124 {
125     struct i965_driver_data *i965 = i965_driver_data(ctx);
126     VAStatus status = VA_STATUS_ERROR_UNIMPLEMENTED;
127     VARectangle aligned_dst_rect;
128     int src_fourcc = pp_get_surface_fourcc(ctx, src_surface);
129     int dst_fourcc = pp_get_surface_fourcc(ctx, dst_surface);
130     unsigned int scale_flag = 0;
131     unsigned int tmp_width, tmp_x;
132
133     /* The Bit 2 is used to indicate that it is 10bit or 8bit.
134      * The Bit 0/1 is used to indicate the 420/422/444 format
135      */
136 #define SRC_8BIT_420     (1 << 0)
137 #define SRC_8BIT_422     (2 << 0)
138 #define SRC_8BIT_444     (3 << 0)
139 #define SRC_10BIT_420    (5 << 0)
140 #define SRC_10BIT_422    (6 << 0)
141 #define SRC_10BIT_444    (7 << 0)
142
143     /* The Bit 6 is used to indicate that it is 10bit or 8bit.
144      * The Bit 5/4 is used to indicate the 420/422/444 format
145      */
146 #define DST_8BIT_420     (1 << 4)
147 #define DST_8BIT_422     (2 << 0)
148 #define DST_8BIT_444     (3 << 0)
149 #define DST_10BIT_420    (5 << 4)
150 #define DST_10BIT_422    (6 << 4)
151 #define DST_10BIT_444    (7 << 4)
152
153 #define SRC_YUV_PACKED   (1 << 3)
154 #define DST_YUV_PACKED   (1 << 7)
155
156 #define SRC_RGB32        (1 << 8)
157 #define DST_RGB32        (1 << 12)
158
159 #define MASK_CSC         (0xFFFF)
160
161 #define SCALE_10BIT_10BIT_420   (SRC_10BIT_420 | DST_10BIT_420)
162 #define SCALE_8BIT_8BIT_420     (SRC_8BIT_420 | DST_8BIT_420)
163 #define SCALE_10BIT420_8BIT422  (SRC_10BIT_420 | DST_8BIT_422 | DST_YUV_PACKED)
164 #define SCALE_10BIT420_8BIT420  (SRC_10BIT_420 | DST_8BIT_420)
165 #define SCALE_8BIT_420_RGB32    (SRC_8BIT_420 | DST_RGB32)
166
167     if (src_fourcc == VA_FOURCC_P010 ||
168         src_fourcc == VA_FOURCC_I010)
169         scale_flag |= SRC_10BIT_420;
170
171     if (src_fourcc == VA_FOURCC_NV12 ||
172         src_fourcc == VA_FOURCC_I420 ||
173         src_fourcc == VA_FOURCC_IMC3 ||
174         src_fourcc == VA_FOURCC_YV12 ||
175         src_fourcc == VA_FOURCC_IMC1)
176         scale_flag |= SRC_8BIT_420;
177
178     if (src_fourcc == VA_FOURCC_YUY2 ||
179         src_fourcc == VA_FOURCC_UYVY)
180         scale_flag |= (SRC_8BIT_422 | SRC_YUV_PACKED);
181
182     if (dst_fourcc == VA_FOURCC_P010 ||
183         dst_fourcc == VA_FOURCC_I010)
184         scale_flag |= DST_10BIT_420;
185
186     if (dst_fourcc == VA_FOURCC_NV12 ||
187         dst_fourcc == VA_FOURCC_I420 ||
188         dst_fourcc == VA_FOURCC_IMC3 ||
189         dst_fourcc == VA_FOURCC_YV12 ||
190         dst_fourcc == VA_FOURCC_IMC1)
191         scale_flag |= DST_8BIT_420;
192
193     if (dst_fourcc == VA_FOURCC_YUY2 ||
194         dst_fourcc == VA_FOURCC_UYVY)
195         scale_flag |= (DST_8BIT_422 | DST_YUV_PACKED);
196
197     if (dst_fourcc == VA_FOURCC_YUY2 ||
198         dst_fourcc == VA_FOURCC_UYVY)
199         scale_flag |= (DST_8BIT_422 | DST_YUV_PACKED);
200
201     if (dst_fourcc == VA_FOURCC_RGBX ||
202         dst_fourcc == VA_FOURCC_RGBA ||
203         dst_fourcc == VA_FOURCC_BGRX ||
204         dst_fourcc == VA_FOURCC_BGRA)
205         scale_flag |= DST_RGB32;
206
207     /* If P010 is converted without resolution change,
208      * fall back to VEBOX
209      */
210     if (i965->intel.has_vebox &&
211         (src_fourcc == VA_FOURCC_P010) &&
212         (dst_fourcc == VA_FOURCC_P010 || dst_fourcc == VA_FOURCC_NV12) &&
213         (src_rect->width == dst_rect->width) &&
214         (src_rect->height == dst_rect->height))
215         scale_flag = 0;
216
217     if (((scale_flag & MASK_CSC) == SCALE_10BIT_10BIT_420) &&
218         (pp_context->scaling_gpe_context_initialized & VPPGPE_10BIT_10BIT)) {
219         unsigned int tmp_width, tmp_x;
220
221         tmp_x = ALIGN_FLOOR(dst_rect->x, 2);
222         tmp_width = dst_rect->x + dst_rect->width - tmp_x;
223         aligned_dst_rect.x = tmp_x;
224         aligned_dst_rect.width = tmp_width;
225         aligned_dst_rect.y = dst_rect->y;
226         aligned_dst_rect.height = dst_rect->height;
227
228         status = gen9_p010_scaling_post_processing(ctx, pp_context,
229                                                    (struct i965_surface *)src_surface, (VARectangle *)src_rect,
230                                                    dst_surface, &aligned_dst_rect);
231     }
232
233     if (((scale_flag & MASK_CSC) == SCALE_8BIT_8BIT_420) &&
234         (pp_context->scaling_gpe_context_initialized & VPPGPE_8BIT_8BIT)) {
235
236         tmp_x = ALIGN_FLOOR(dst_rect->x, 4);
237         tmp_width = dst_rect->x + dst_rect->width - tmp_x;
238         aligned_dst_rect.x = tmp_x;
239         aligned_dst_rect.width = tmp_width;
240         aligned_dst_rect.y = dst_rect->y;
241         aligned_dst_rect.height = dst_rect->height;
242
243         status = intel_yuv420p8_scaling_post_processing(ctx, pp_context,
244                                                         (struct i965_surface *)src_surface, (VARectangle *)src_rect,
245                                                         dst_surface, &aligned_dst_rect);
246     }
247
248     if (((scale_flag & MASK_CSC) == SCALE_10BIT420_8BIT420 ||
249          (scale_flag & MASK_CSC) == SCALE_10BIT420_8BIT422) &&
250         (pp_context->scaling_gpe_context_initialized & VPPGPE_10BIT_8BIT)) {
251
252         tmp_x = ALIGN_FLOOR(dst_rect->x, 4);
253         tmp_width = dst_rect->x + dst_rect->width - tmp_x;
254         aligned_dst_rect.x = tmp_x;
255         aligned_dst_rect.width = tmp_width;
256         aligned_dst_rect.y = dst_rect->y;
257         aligned_dst_rect.height = dst_rect->height;
258
259         status = intel_10bit_8bit_scaling_post_processing(ctx, pp_context,
260                                                           (struct i965_surface *)src_surface, (VARectangle *)src_rect,
261                                                           dst_surface, &aligned_dst_rect);
262     }
263
264     if (((scale_flag & MASK_CSC) == SCALE_8BIT_420_RGB32) &&
265         (pp_context->scaling_gpe_context_initialized & VPPGPE_8BIT_420_RGB32)) {
266         tmp_x = ALIGN_FLOOR(dst_rect->x, 4);
267         tmp_width = dst_rect->x + dst_rect->width - tmp_x;
268         aligned_dst_rect.x = tmp_x;
269         aligned_dst_rect.width = tmp_width;
270         aligned_dst_rect.y = dst_rect->y;
271         aligned_dst_rect.height = dst_rect->height;
272
273         status = intel_8bit_420_rgb32_scaling_post_processing(ctx, pp_context,
274                                                               (struct i965_surface *)src_surface, (VARectangle *)src_rect,
275                                                               dst_surface, &aligned_dst_rect);
276     }
277
278     return status;
279 }