xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/va/postproc.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /**************************************************************************
2*61046927SAndroid Build Coastguard Worker  *
3*61046927SAndroid Build Coastguard Worker  * Copyright 2015 Advanced Micro Devices, Inc.
4*61046927SAndroid Build Coastguard Worker  * All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker  *
6*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the
8*61046927SAndroid Build Coastguard Worker  * "Software"), to deal in the Software without restriction, including
9*61046927SAndroid Build Coastguard Worker  * without limitation the rights to use, copy, modify, merge, publish,
10*61046927SAndroid Build Coastguard Worker  * distribute, sub license, and/or sell copies of the Software, and to
11*61046927SAndroid Build Coastguard Worker  * permit persons to whom the Software is furnished to do so, subject to
12*61046927SAndroid Build Coastguard Worker  * the following conditions:
13*61046927SAndroid Build Coastguard Worker  *
14*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the
15*61046927SAndroid Build Coastguard Worker  * next paragraph) shall be included in all copies or substantial portions
16*61046927SAndroid Build Coastguard Worker  * of the Software.
17*61046927SAndroid Build Coastguard Worker  *
18*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19*61046927SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20*61046927SAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21*61046927SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22*61046927SAndroid Build Coastguard Worker  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23*61046927SAndroid Build Coastguard Worker  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24*61046927SAndroid Build Coastguard Worker  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25*61046927SAndroid Build Coastguard Worker  *
26*61046927SAndroid Build Coastguard Worker  **************************************************************************/
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker #include "util/u_handle_table.h"
29*61046927SAndroid Build Coastguard Worker #include "util/u_memory.h"
30*61046927SAndroid Build Coastguard Worker #include "util/u_compute.h"
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker #include "vl/vl_defines.h"
33*61046927SAndroid Build Coastguard Worker #include "vl/vl_video_buffer.h"
34*61046927SAndroid Build Coastguard Worker #include "vl/vl_deint_filter.h"
35*61046927SAndroid Build Coastguard Worker #include "vl/vl_winsys.h"
36*61046927SAndroid Build Coastguard Worker 
37*61046927SAndroid Build Coastguard Worker #include "va_private.h"
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker static const VARectangle *
vlVaRegionDefault(const VARectangle * region,vlVaSurface * surf,VARectangle * def)40*61046927SAndroid Build Coastguard Worker vlVaRegionDefault(const VARectangle *region, vlVaSurface *surf,
41*61046927SAndroid Build Coastguard Worker 		  VARectangle *def)
42*61046927SAndroid Build Coastguard Worker {
43*61046927SAndroid Build Coastguard Worker    if (region)
44*61046927SAndroid Build Coastguard Worker       return region;
45*61046927SAndroid Build Coastguard Worker 
46*61046927SAndroid Build Coastguard Worker    def->x = 0;
47*61046927SAndroid Build Coastguard Worker    def->y = 0;
48*61046927SAndroid Build Coastguard Worker    def->width = surf->templat.width;
49*61046927SAndroid Build Coastguard Worker    def->height = surf->templat.height;
50*61046927SAndroid Build Coastguard Worker 
51*61046927SAndroid Build Coastguard Worker    return def;
52*61046927SAndroid Build Coastguard Worker }
53*61046927SAndroid Build Coastguard Worker 
54*61046927SAndroid Build Coastguard Worker static VAStatus
vlVaPostProcCompositor(vlVaDriver * drv,vlVaContext * context,const VARectangle * src_region,const VARectangle * dst_region,struct pipe_video_buffer * src,struct pipe_video_buffer * dst,enum vl_compositor_deinterlace deinterlace)55*61046927SAndroid Build Coastguard Worker vlVaPostProcCompositor(vlVaDriver *drv, vlVaContext *context,
56*61046927SAndroid Build Coastguard Worker                        const VARectangle *src_region,
57*61046927SAndroid Build Coastguard Worker                        const VARectangle *dst_region,
58*61046927SAndroid Build Coastguard Worker                        struct pipe_video_buffer *src,
59*61046927SAndroid Build Coastguard Worker                        struct pipe_video_buffer *dst,
60*61046927SAndroid Build Coastguard Worker                        enum vl_compositor_deinterlace deinterlace)
61*61046927SAndroid Build Coastguard Worker {
62*61046927SAndroid Build Coastguard Worker    struct pipe_surface **surfaces;
63*61046927SAndroid Build Coastguard Worker    struct u_rect src_rect;
64*61046927SAndroid Build Coastguard Worker    struct u_rect dst_rect;
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker    surfaces = dst->get_surfaces(dst);
67*61046927SAndroid Build Coastguard Worker    if (!surfaces || !surfaces[0])
68*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_SURFACE;
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    src_rect.x0 = src_region->x;
71*61046927SAndroid Build Coastguard Worker    src_rect.y0 = src_region->y;
72*61046927SAndroid Build Coastguard Worker    src_rect.x1 = src_region->x + src_region->width;
73*61046927SAndroid Build Coastguard Worker    src_rect.y1 = src_region->y + src_region->height;
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker    dst_rect.x0 = dst_region->x;
76*61046927SAndroid Build Coastguard Worker    dst_rect.y0 = dst_region->y;
77*61046927SAndroid Build Coastguard Worker    dst_rect.x1 = dst_region->x + dst_region->width;
78*61046927SAndroid Build Coastguard Worker    dst_rect.y1 = dst_region->y + dst_region->height;
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker    vl_compositor_clear_layers(&drv->cstate);
81*61046927SAndroid Build Coastguard Worker    vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, src,
82*61046927SAndroid Build Coastguard Worker 				  &src_rect, NULL, deinterlace);
83*61046927SAndroid Build Coastguard Worker    vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dst_rect);
84*61046927SAndroid Build Coastguard Worker    vl_compositor_render(&drv->cstate, &drv->compositor, surfaces[0], NULL, false);
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker    drv->pipe->flush(drv->pipe, NULL, 0);
87*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
88*61046927SAndroid Build Coastguard Worker }
89*61046927SAndroid Build Coastguard Worker 
vlVaGetBox(struct pipe_video_buffer * buf,unsigned idx,struct pipe_box * box,const VARectangle * region)90*61046927SAndroid Build Coastguard Worker static void vlVaGetBox(struct pipe_video_buffer *buf, unsigned idx,
91*61046927SAndroid Build Coastguard Worker                        struct pipe_box *box, const VARectangle *region)
92*61046927SAndroid Build Coastguard Worker {
93*61046927SAndroid Build Coastguard Worker    unsigned plane = buf->interlaced ? idx / 2: idx;
94*61046927SAndroid Build Coastguard Worker    unsigned x, y, width, height;
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker    x = abs(region->x);
97*61046927SAndroid Build Coastguard Worker    y = abs(region->y);
98*61046927SAndroid Build Coastguard Worker    width = region->width;
99*61046927SAndroid Build Coastguard Worker    height = region->height;
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker    vl_video_buffer_adjust_size(&x, &y, plane,
102*61046927SAndroid Build Coastguard Worker                                pipe_format_to_chroma_format(buf->buffer_format),
103*61046927SAndroid Build Coastguard Worker                                buf->interlaced);
104*61046927SAndroid Build Coastguard Worker    vl_video_buffer_adjust_size(&width, &height, plane,
105*61046927SAndroid Build Coastguard Worker                                pipe_format_to_chroma_format(buf->buffer_format),
106*61046927SAndroid Build Coastguard Worker                                buf->interlaced);
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker    box->x = region->x < 0 ? -x : x;
109*61046927SAndroid Build Coastguard Worker    box->y = region->y < 0 ? -y : y;
110*61046927SAndroid Build Coastguard Worker    box->width = width;
111*61046927SAndroid Build Coastguard Worker    box->height = height;
112*61046927SAndroid Build Coastguard Worker }
113*61046927SAndroid Build Coastguard Worker 
vlVaGetFullRange(vlVaSurface * surface,uint8_t va_range)114*61046927SAndroid Build Coastguard Worker static bool vlVaGetFullRange(vlVaSurface *surface, uint8_t va_range)
115*61046927SAndroid Build Coastguard Worker {
116*61046927SAndroid Build Coastguard Worker    if (va_range != VA_SOURCE_RANGE_UNKNOWN)
117*61046927SAndroid Build Coastguard Worker       return va_range == VA_SOURCE_RANGE_FULL;
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    /* Assume limited for YUV, full for RGB */
120*61046927SAndroid Build Coastguard Worker    return !util_format_is_yuv(surface->buffer->buffer_format);
121*61046927SAndroid Build Coastguard Worker }
122*61046927SAndroid Build Coastguard Worker 
vlVaGetChromaLocation(unsigned va_chroma_location,enum pipe_format format)123*61046927SAndroid Build Coastguard Worker static unsigned vlVaGetChromaLocation(unsigned va_chroma_location,
124*61046927SAndroid Build Coastguard Worker                                       enum pipe_format format)
125*61046927SAndroid Build Coastguard Worker {
126*61046927SAndroid Build Coastguard Worker    unsigned ret = VL_COMPOSITOR_LOCATION_NONE;
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker    if (util_format_get_plane_height(format, 1, 4) != 4) {
129*61046927SAndroid Build Coastguard Worker       /* Bits 0-1 */
130*61046927SAndroid Build Coastguard Worker       switch (va_chroma_location & 3) {
131*61046927SAndroid Build Coastguard Worker       case VA_CHROMA_SITING_VERTICAL_TOP:
132*61046927SAndroid Build Coastguard Worker          ret |= VL_COMPOSITOR_LOCATION_VERTICAL_TOP;
133*61046927SAndroid Build Coastguard Worker          break;
134*61046927SAndroid Build Coastguard Worker       case VA_CHROMA_SITING_VERTICAL_BOTTOM:
135*61046927SAndroid Build Coastguard Worker          ret |= VL_COMPOSITOR_LOCATION_VERTICAL_BOTTOM;
136*61046927SAndroid Build Coastguard Worker          break;
137*61046927SAndroid Build Coastguard Worker       case VA_CHROMA_SITING_VERTICAL_CENTER:
138*61046927SAndroid Build Coastguard Worker       default:
139*61046927SAndroid Build Coastguard Worker          ret |= VL_COMPOSITOR_LOCATION_VERTICAL_CENTER;
140*61046927SAndroid Build Coastguard Worker          break;
141*61046927SAndroid Build Coastguard Worker       }
142*61046927SAndroid Build Coastguard Worker    }
143*61046927SAndroid Build Coastguard Worker 
144*61046927SAndroid Build Coastguard Worker    if (util_format_is_subsampled_422(format) ||
145*61046927SAndroid Build Coastguard Worker        util_format_get_plane_width(format, 1, 4) != 4) {
146*61046927SAndroid Build Coastguard Worker       /* Bits 2-3 */
147*61046927SAndroid Build Coastguard Worker       switch (va_chroma_location & 12) {
148*61046927SAndroid Build Coastguard Worker       case VA_CHROMA_SITING_HORIZONTAL_CENTER:
149*61046927SAndroid Build Coastguard Worker          ret |= VL_COMPOSITOR_LOCATION_HORIZONTAL_CENTER;
150*61046927SAndroid Build Coastguard Worker          break;
151*61046927SAndroid Build Coastguard Worker       case VA_CHROMA_SITING_HORIZONTAL_LEFT:
152*61046927SAndroid Build Coastguard Worker       default:
153*61046927SAndroid Build Coastguard Worker          ret |= VL_COMPOSITOR_LOCATION_HORIZONTAL_LEFT;
154*61046927SAndroid Build Coastguard Worker          break;
155*61046927SAndroid Build Coastguard Worker       }
156*61046927SAndroid Build Coastguard Worker    }
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker    return ret;
159*61046927SAndroid Build Coastguard Worker }
160*61046927SAndroid Build Coastguard Worker 
vlVaSetProcParameters(vlVaDriver * drv,vlVaSurface * src,vlVaSurface * dst,VAProcPipelineParameterBuffer * param)161*61046927SAndroid Build Coastguard Worker static void vlVaSetProcParameters(vlVaDriver *drv,
162*61046927SAndroid Build Coastguard Worker                                   vlVaSurface *src,
163*61046927SAndroid Build Coastguard Worker                                   vlVaSurface *dst,
164*61046927SAndroid Build Coastguard Worker                                   VAProcPipelineParameterBuffer *param)
165*61046927SAndroid Build Coastguard Worker {
166*61046927SAndroid Build Coastguard Worker    enum VL_CSC_COLOR_STANDARD color_standard;
167*61046927SAndroid Build Coastguard Worker    bool src_yuv = util_format_is_yuv(src->buffer->buffer_format);
168*61046927SAndroid Build Coastguard Worker    bool dst_yuv = util_format_is_yuv(dst->buffer->buffer_format);
169*61046927SAndroid Build Coastguard Worker 
170*61046927SAndroid Build Coastguard Worker    if (src_yuv == dst_yuv) {
171*61046927SAndroid Build Coastguard Worker       color_standard = VL_CSC_COLOR_STANDARD_IDENTITY;
172*61046927SAndroid Build Coastguard Worker    } else if (src_yuv) {
173*61046927SAndroid Build Coastguard Worker       switch (param->surface_color_standard) {
174*61046927SAndroid Build Coastguard Worker       case VAProcColorStandardBT601:
175*61046927SAndroid Build Coastguard Worker          color_standard = VL_CSC_COLOR_STANDARD_BT_601;
176*61046927SAndroid Build Coastguard Worker          break;
177*61046927SAndroid Build Coastguard Worker       case VAProcColorStandardBT709:
178*61046927SAndroid Build Coastguard Worker       default:
179*61046927SAndroid Build Coastguard Worker          color_standard = src->full_range ?
180*61046927SAndroid Build Coastguard Worker             VL_CSC_COLOR_STANDARD_BT_709_FULL :
181*61046927SAndroid Build Coastguard Worker             VL_CSC_COLOR_STANDARD_BT_709;
182*61046927SAndroid Build Coastguard Worker          break;
183*61046927SAndroid Build Coastguard Worker       }
184*61046927SAndroid Build Coastguard Worker    } else {
185*61046927SAndroid Build Coastguard Worker       color_standard = VL_CSC_COLOR_STANDARD_BT_709_REV;
186*61046927SAndroid Build Coastguard Worker    }
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker    vl_csc_get_matrix(color_standard, NULL, dst->full_range, &drv->csc);
189*61046927SAndroid Build Coastguard Worker    vl_compositor_set_csc_matrix(&drv->cstate, &drv->csc, 1.0f, 0.0f);
190*61046927SAndroid Build Coastguard Worker 
191*61046927SAndroid Build Coastguard Worker    if (src_yuv)
192*61046927SAndroid Build Coastguard Worker       drv->cstate.chroma_location =
193*61046927SAndroid Build Coastguard Worker          vlVaGetChromaLocation(param->input_color_properties.chroma_sample_location,
194*61046927SAndroid Build Coastguard Worker                                src->buffer->buffer_format);
195*61046927SAndroid Build Coastguard Worker    else if (dst_yuv)
196*61046927SAndroid Build Coastguard Worker       drv->cstate.chroma_location =
197*61046927SAndroid Build Coastguard Worker          vlVaGetChromaLocation(param->output_color_properties.chroma_sample_location,
198*61046927SAndroid Build Coastguard Worker                                dst->buffer->buffer_format);
199*61046927SAndroid Build Coastguard Worker }
200*61046927SAndroid Build Coastguard Worker 
vlVaVidEngineBlit(vlVaDriver * drv,vlVaContext * context,const VARectangle * src_region,const VARectangle * dst_region,struct pipe_video_buffer * src,struct pipe_video_buffer * dst,enum vl_compositor_deinterlace deinterlace,VAProcPipelineParameterBuffer * param)201*61046927SAndroid Build Coastguard Worker static VAStatus vlVaVidEngineBlit(vlVaDriver *drv, vlVaContext *context,
202*61046927SAndroid Build Coastguard Worker                                  const VARectangle *src_region,
203*61046927SAndroid Build Coastguard Worker                                  const VARectangle *dst_region,
204*61046927SAndroid Build Coastguard Worker                                  struct pipe_video_buffer *src,
205*61046927SAndroid Build Coastguard Worker                                  struct pipe_video_buffer *dst,
206*61046927SAndroid Build Coastguard Worker                                  enum vl_compositor_deinterlace deinterlace,
207*61046927SAndroid Build Coastguard Worker                                  VAProcPipelineParameterBuffer* param)
208*61046927SAndroid Build Coastguard Worker {
209*61046927SAndroid Build Coastguard Worker    if (deinterlace != VL_COMPOSITOR_NONE)
210*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_UNIMPLEMENTED;
211*61046927SAndroid Build Coastguard Worker 
212*61046927SAndroid Build Coastguard Worker    if (!drv->pipe->screen->is_video_format_supported(drv->pipe->screen,
213*61046927SAndroid Build Coastguard Worker                                                      src->buffer_format,
214*61046927SAndroid Build Coastguard Worker                                                      PIPE_VIDEO_PROFILE_UNKNOWN,
215*61046927SAndroid Build Coastguard Worker                                                      PIPE_VIDEO_ENTRYPOINT_PROCESSING))
216*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker    if (!drv->pipe->screen->is_video_format_supported(drv->pipe->screen,
219*61046927SAndroid Build Coastguard Worker                                                      dst->buffer_format,
220*61046927SAndroid Build Coastguard Worker                                                      PIPE_VIDEO_PROFILE_UNKNOWN,
221*61046927SAndroid Build Coastguard Worker                                                      PIPE_VIDEO_ENTRYPOINT_PROCESSING))
222*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
223*61046927SAndroid Build Coastguard Worker 
224*61046927SAndroid Build Coastguard Worker    struct u_rect src_rect;
225*61046927SAndroid Build Coastguard Worker    struct u_rect dst_rect;
226*61046927SAndroid Build Coastguard Worker 
227*61046927SAndroid Build Coastguard Worker    src_rect.x0 = src_region->x;
228*61046927SAndroid Build Coastguard Worker    src_rect.y0 = src_region->y;
229*61046927SAndroid Build Coastguard Worker    src_rect.x1 = src_region->x + src_region->width;
230*61046927SAndroid Build Coastguard Worker    src_rect.y1 = src_region->y + src_region->height;
231*61046927SAndroid Build Coastguard Worker 
232*61046927SAndroid Build Coastguard Worker    dst_rect.x0 = dst_region->x;
233*61046927SAndroid Build Coastguard Worker    dst_rect.y0 = dst_region->y;
234*61046927SAndroid Build Coastguard Worker    dst_rect.x1 = dst_region->x + dst_region->width;
235*61046927SAndroid Build Coastguard Worker    dst_rect.y1 = dst_region->y + dst_region->height;
236*61046927SAndroid Build Coastguard Worker 
237*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.base.input_format = src->buffer_format;
238*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.base.output_format = dst->buffer_format;
239*61046927SAndroid Build Coastguard Worker 
240*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.src_region = src_rect;
241*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.dst_region = dst_rect;
242*61046927SAndroid Build Coastguard Worker 
243*61046927SAndroid Build Coastguard Worker    if (param->rotation_state == VA_ROTATION_NONE)
244*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.orientation = PIPE_VIDEO_VPP_ORIENTATION_DEFAULT;
245*61046927SAndroid Build Coastguard Worker    else if (param->rotation_state == VA_ROTATION_90)
246*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.orientation = PIPE_VIDEO_VPP_ROTATION_90;
247*61046927SAndroid Build Coastguard Worker    else if (param->rotation_state == VA_ROTATION_180)
248*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.orientation = PIPE_VIDEO_VPP_ROTATION_180;
249*61046927SAndroid Build Coastguard Worker    else if (param->rotation_state == VA_ROTATION_270)
250*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.orientation = PIPE_VIDEO_VPP_ROTATION_270;
251*61046927SAndroid Build Coastguard Worker 
252*61046927SAndroid Build Coastguard Worker    if (param->mirror_state == VA_MIRROR_HORIZONTAL)
253*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.orientation |= PIPE_VIDEO_VPP_FLIP_HORIZONTAL;
254*61046927SAndroid Build Coastguard Worker    if (param->mirror_state == VA_MIRROR_VERTICAL)
255*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.orientation |= PIPE_VIDEO_VPP_FLIP_VERTICAL;
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker    memset(&context->desc.vidproc.blend, 0, sizeof(context->desc.vidproc.blend));
258*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.blend.mode = PIPE_VIDEO_VPP_BLEND_MODE_NONE;
259*61046927SAndroid Build Coastguard Worker    if (param->blend_state != NULL) {
260*61046927SAndroid Build Coastguard Worker       if (param->blend_state->flags & VA_BLEND_GLOBAL_ALPHA) {
261*61046927SAndroid Build Coastguard Worker          context->desc.vidproc.blend.mode = PIPE_VIDEO_VPP_BLEND_MODE_GLOBAL_ALPHA;
262*61046927SAndroid Build Coastguard Worker          context->desc.vidproc.blend.global_alpha = param->blend_state->global_alpha;
263*61046927SAndroid Build Coastguard Worker       }
264*61046927SAndroid Build Coastguard Worker    }
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker    // Output background color
267*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.background_color = param->output_background_color;
268*61046927SAndroid Build Coastguard Worker 
269*61046927SAndroid Build Coastguard Worker    // Input surface color standard
270*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.in_colors_standard = PIPE_VIDEO_VPP_COLOR_STANDARD_TYPE_NONE;
271*61046927SAndroid Build Coastguard Worker    if (param->surface_color_standard == VAProcColorStandardBT601)
272*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.in_colors_standard = PIPE_VIDEO_VPP_COLOR_STANDARD_TYPE_BT601;
273*61046927SAndroid Build Coastguard Worker    else if (param->surface_color_standard == VAProcColorStandardBT709)
274*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.in_colors_standard = PIPE_VIDEO_VPP_COLOR_STANDARD_TYPE_BT709;
275*61046927SAndroid Build Coastguard Worker    else if (param->surface_color_standard == VAProcColorStandardBT2020)
276*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.in_colors_standard = PIPE_VIDEO_VPP_COLOR_STANDARD_TYPE_BT2020;
277*61046927SAndroid Build Coastguard Worker 
278*61046927SAndroid Build Coastguard Worker    // Input surface color range
279*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.in_color_range = PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_NONE;
280*61046927SAndroid Build Coastguard Worker    if (param->input_color_properties.color_range == VA_SOURCE_RANGE_REDUCED)
281*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.in_color_range = PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_REDUCED;
282*61046927SAndroid Build Coastguard Worker    else if (param->input_color_properties.color_range == VA_SOURCE_RANGE_FULL)
283*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.in_color_range = PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_FULL;
284*61046927SAndroid Build Coastguard Worker 
285*61046927SAndroid Build Coastguard Worker    // Input surface chroma sample location
286*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.in_chroma_siting = PIPE_VIDEO_VPP_CHROMA_SITING_NONE;
287*61046927SAndroid Build Coastguard Worker    if (param->input_color_properties.chroma_sample_location & VA_CHROMA_SITING_VERTICAL_TOP)
288*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.in_chroma_siting |= PIPE_VIDEO_VPP_CHROMA_SITING_VERTICAL_TOP;
289*61046927SAndroid Build Coastguard Worker    else if (param->input_color_properties.chroma_sample_location & VA_CHROMA_SITING_VERTICAL_CENTER)
290*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.in_chroma_siting |= PIPE_VIDEO_VPP_CHROMA_SITING_VERTICAL_CENTER;
291*61046927SAndroid Build Coastguard Worker    else if (param->input_color_properties.chroma_sample_location & VA_CHROMA_SITING_VERTICAL_BOTTOM)
292*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.in_chroma_siting |= PIPE_VIDEO_VPP_CHROMA_SITING_VERTICAL_BOTTOM;
293*61046927SAndroid Build Coastguard Worker    if (param->input_color_properties.chroma_sample_location & VA_CHROMA_SITING_HORIZONTAL_LEFT)
294*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.in_chroma_siting |= PIPE_VIDEO_VPP_CHROMA_SITING_HORIZONTAL_LEFT;
295*61046927SAndroid Build Coastguard Worker    else if (param->input_color_properties.chroma_sample_location & VA_CHROMA_SITING_HORIZONTAL_CENTER)
296*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.in_chroma_siting |= PIPE_VIDEO_VPP_CHROMA_SITING_HORIZONTAL_CENTER;
297*61046927SAndroid Build Coastguard Worker 
298*61046927SAndroid Build Coastguard Worker    // Output surface color standard
299*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.out_colors_standard = PIPE_VIDEO_VPP_COLOR_STANDARD_TYPE_NONE;
300*61046927SAndroid Build Coastguard Worker    if (param->output_color_standard == VAProcColorStandardBT601)
301*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.out_colors_standard = PIPE_VIDEO_VPP_COLOR_STANDARD_TYPE_BT601;
302*61046927SAndroid Build Coastguard Worker    else if (param->output_color_standard == VAProcColorStandardBT709)
303*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.out_colors_standard = PIPE_VIDEO_VPP_COLOR_STANDARD_TYPE_BT709;
304*61046927SAndroid Build Coastguard Worker    else if (param->output_color_standard == VAProcColorStandardBT2020)
305*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.out_colors_standard = PIPE_VIDEO_VPP_COLOR_STANDARD_TYPE_BT2020;
306*61046927SAndroid Build Coastguard Worker 
307*61046927SAndroid Build Coastguard Worker    // Output surface color range
308*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.out_color_range = PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_NONE;
309*61046927SAndroid Build Coastguard Worker    if (param->output_color_properties.color_range == VA_SOURCE_RANGE_REDUCED)
310*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.out_color_range = PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_REDUCED;
311*61046927SAndroid Build Coastguard Worker    else if (param->output_color_properties.color_range == VA_SOURCE_RANGE_FULL)
312*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.out_color_range = PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_FULL;
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker    // Output surface chroma sample location
315*61046927SAndroid Build Coastguard Worker    context->desc.vidproc.out_chroma_siting = PIPE_VIDEO_VPP_CHROMA_SITING_NONE;
316*61046927SAndroid Build Coastguard Worker    if (param->output_color_properties.chroma_sample_location & VA_CHROMA_SITING_VERTICAL_TOP)
317*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.out_chroma_siting |= PIPE_VIDEO_VPP_CHROMA_SITING_VERTICAL_TOP;
318*61046927SAndroid Build Coastguard Worker    else if (param->output_color_properties.chroma_sample_location & VA_CHROMA_SITING_VERTICAL_CENTER)
319*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.out_chroma_siting |= PIPE_VIDEO_VPP_CHROMA_SITING_VERTICAL_CENTER;
320*61046927SAndroid Build Coastguard Worker    else if (param->output_color_properties.chroma_sample_location & VA_CHROMA_SITING_VERTICAL_BOTTOM)
321*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.out_chroma_siting |= PIPE_VIDEO_VPP_CHROMA_SITING_VERTICAL_BOTTOM;
322*61046927SAndroid Build Coastguard Worker    if (param->output_color_properties.chroma_sample_location & VA_CHROMA_SITING_HORIZONTAL_LEFT)
323*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.out_chroma_siting |= PIPE_VIDEO_VPP_CHROMA_SITING_HORIZONTAL_LEFT;
324*61046927SAndroid Build Coastguard Worker    else if (param->output_color_properties.chroma_sample_location & VA_CHROMA_SITING_HORIZONTAL_CENTER)
325*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.out_chroma_siting |= PIPE_VIDEO_VPP_CHROMA_SITING_HORIZONTAL_CENTER;
326*61046927SAndroid Build Coastguard Worker 
327*61046927SAndroid Build Coastguard Worker    if (context->needs_begin_frame) {
328*61046927SAndroid Build Coastguard Worker       context->decoder->begin_frame(context->decoder, dst,
329*61046927SAndroid Build Coastguard Worker                                     &context->desc.base);
330*61046927SAndroid Build Coastguard Worker       context->needs_begin_frame = false;
331*61046927SAndroid Build Coastguard Worker    }
332*61046927SAndroid Build Coastguard Worker    context->decoder->process_frame(context->decoder, src, &context->desc.vidproc);
333*61046927SAndroid Build Coastguard Worker 
334*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
335*61046927SAndroid Build Coastguard Worker }
336*61046927SAndroid Build Coastguard Worker 
vlVaPostProcBlit(vlVaDriver * drv,vlVaContext * context,const VARectangle * src_region,const VARectangle * dst_region,struct pipe_video_buffer * src,struct pipe_video_buffer * dst,enum vl_compositor_deinterlace deinterlace)337*61046927SAndroid Build Coastguard Worker static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context,
338*61046927SAndroid Build Coastguard Worker                                  const VARectangle *src_region,
339*61046927SAndroid Build Coastguard Worker                                  const VARectangle *dst_region,
340*61046927SAndroid Build Coastguard Worker                                  struct pipe_video_buffer *src,
341*61046927SAndroid Build Coastguard Worker                                  struct pipe_video_buffer *dst,
342*61046927SAndroid Build Coastguard Worker                                  enum vl_compositor_deinterlace deinterlace)
343*61046927SAndroid Build Coastguard Worker {
344*61046927SAndroid Build Coastguard Worker    struct pipe_surface **src_surfaces;
345*61046927SAndroid Build Coastguard Worker    struct pipe_surface **dst_surfaces;
346*61046927SAndroid Build Coastguard Worker    struct u_rect src_rect;
347*61046927SAndroid Build Coastguard Worker    struct u_rect dst_rect;
348*61046927SAndroid Build Coastguard Worker    bool scale = false;
349*61046927SAndroid Build Coastguard Worker    bool grab = false;
350*61046927SAndroid Build Coastguard Worker    unsigned i;
351*61046927SAndroid Build Coastguard Worker 
352*61046927SAndroid Build Coastguard Worker    if ((src->buffer_format == PIPE_FORMAT_B8G8R8X8_UNORM ||
353*61046927SAndroid Build Coastguard Worker         src->buffer_format == PIPE_FORMAT_B8G8R8A8_UNORM ||
354*61046927SAndroid Build Coastguard Worker         src->buffer_format == PIPE_FORMAT_R8G8B8X8_UNORM ||
355*61046927SAndroid Build Coastguard Worker         src->buffer_format == PIPE_FORMAT_R8G8B8A8_UNORM ||
356*61046927SAndroid Build Coastguard Worker         src->buffer_format == PIPE_FORMAT_B10G10R10X2_UNORM ||
357*61046927SAndroid Build Coastguard Worker         src->buffer_format == PIPE_FORMAT_B10G10R10A2_UNORM ||
358*61046927SAndroid Build Coastguard Worker         src->buffer_format == PIPE_FORMAT_R10G10B10X2_UNORM ||
359*61046927SAndroid Build Coastguard Worker         src->buffer_format == PIPE_FORMAT_R10G10B10A2_UNORM) &&
360*61046927SAndroid Build Coastguard Worker        !src->interlaced)
361*61046927SAndroid Build Coastguard Worker       grab = true;
362*61046927SAndroid Build Coastguard Worker 
363*61046927SAndroid Build Coastguard Worker    if ((src->width != dst->width || src->height != dst->height) &&
364*61046927SAndroid Build Coastguard Worker        (src->interlaced && dst->interlaced))
365*61046927SAndroid Build Coastguard Worker       scale = true;
366*61046927SAndroid Build Coastguard Worker 
367*61046927SAndroid Build Coastguard Worker    src_surfaces = src->get_surfaces(src);
368*61046927SAndroid Build Coastguard Worker    if (!src_surfaces || !src_surfaces[0])
369*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_SURFACE;
370*61046927SAndroid Build Coastguard Worker 
371*61046927SAndroid Build Coastguard Worker    if (scale || (src->interlaced != dst->interlaced && dst->interlaced)) {
372*61046927SAndroid Build Coastguard Worker       vlVaSurface *surf;
373*61046927SAndroid Build Coastguard Worker 
374*61046927SAndroid Build Coastguard Worker       surf = handle_table_get(drv->htab, context->target_id);
375*61046927SAndroid Build Coastguard Worker       if (!surf)
376*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_INVALID_SURFACE;
377*61046927SAndroid Build Coastguard Worker       surf->templat.interlaced = false;
378*61046927SAndroid Build Coastguard Worker       dst->destroy(dst);
379*61046927SAndroid Build Coastguard Worker 
380*61046927SAndroid Build Coastguard Worker       if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS)
381*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_ALLOCATION_FAILED;
382*61046927SAndroid Build Coastguard Worker 
383*61046927SAndroid Build Coastguard Worker       dst = context->target = surf->buffer;
384*61046927SAndroid Build Coastguard Worker    }
385*61046927SAndroid Build Coastguard Worker 
386*61046927SAndroid Build Coastguard Worker    dst_surfaces = dst->get_surfaces(dst);
387*61046927SAndroid Build Coastguard Worker    if (!dst_surfaces || !dst_surfaces[0])
388*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_SURFACE;
389*61046927SAndroid Build Coastguard Worker 
390*61046927SAndroid Build Coastguard Worker    src_rect.x0 = src_region->x;
391*61046927SAndroid Build Coastguard Worker    src_rect.y0 = src_region->y;
392*61046927SAndroid Build Coastguard Worker    src_rect.x1 = src_region->x + src_region->width;
393*61046927SAndroid Build Coastguard Worker    src_rect.y1 = src_region->y + src_region->height;
394*61046927SAndroid Build Coastguard Worker 
395*61046927SAndroid Build Coastguard Worker    dst_rect.x0 = dst_region->x;
396*61046927SAndroid Build Coastguard Worker    dst_rect.y0 = dst_region->y;
397*61046927SAndroid Build Coastguard Worker    dst_rect.x1 = dst_region->x + dst_region->width;
398*61046927SAndroid Build Coastguard Worker    dst_rect.y1 = dst_region->y + dst_region->height;
399*61046927SAndroid Build Coastguard Worker 
400*61046927SAndroid Build Coastguard Worker    if (grab) {
401*61046927SAndroid Build Coastguard Worker       vl_compositor_convert_rgb_to_yuv(&drv->cstate, &drv->compositor, 0,
402*61046927SAndroid Build Coastguard Worker                                        ((struct vl_video_buffer *)src)->resources[0],
403*61046927SAndroid Build Coastguard Worker                                        dst, &src_rect, &dst_rect);
404*61046927SAndroid Build Coastguard Worker 
405*61046927SAndroid Build Coastguard Worker       return VA_STATUS_SUCCESS;
406*61046927SAndroid Build Coastguard Worker    }
407*61046927SAndroid Build Coastguard Worker 
408*61046927SAndroid Build Coastguard Worker    if (src->buffer_format == PIPE_FORMAT_YUYV ||
409*61046927SAndroid Build Coastguard Worker        src->buffer_format == PIPE_FORMAT_UYVY ||
410*61046927SAndroid Build Coastguard Worker        src->buffer_format == PIPE_FORMAT_YV12 ||
411*61046927SAndroid Build Coastguard Worker        src->buffer_format == PIPE_FORMAT_IYUV) {
412*61046927SAndroid Build Coastguard Worker       vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor,
413*61046927SAndroid Build Coastguard Worker                                    src, dst, &src_rect, &dst_rect,
414*61046927SAndroid Build Coastguard Worker                                    VL_COMPOSITOR_NONE);
415*61046927SAndroid Build Coastguard Worker 
416*61046927SAndroid Build Coastguard Worker       return VA_STATUS_SUCCESS;
417*61046927SAndroid Build Coastguard Worker    }
418*61046927SAndroid Build Coastguard Worker 
419*61046927SAndroid Build Coastguard Worker    if (src->interlaced != dst->interlaced) {
420*61046927SAndroid Build Coastguard Worker       deinterlace = deinterlace ? deinterlace : VL_COMPOSITOR_WEAVE;
421*61046927SAndroid Build Coastguard Worker       vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor,
422*61046927SAndroid Build Coastguard Worker                                    src, dst, &src_rect, &dst_rect,
423*61046927SAndroid Build Coastguard Worker                                    deinterlace);
424*61046927SAndroid Build Coastguard Worker 
425*61046927SAndroid Build Coastguard Worker       return VA_STATUS_SUCCESS;
426*61046927SAndroid Build Coastguard Worker    }
427*61046927SAndroid Build Coastguard Worker 
428*61046927SAndroid Build Coastguard Worker    for (i = 0; i < VL_MAX_SURFACES; ++i) {
429*61046927SAndroid Build Coastguard Worker       struct pipe_surface *from = src_surfaces[i];
430*61046927SAndroid Build Coastguard Worker       struct pipe_blit_info blit;
431*61046927SAndroid Build Coastguard Worker 
432*61046927SAndroid Build Coastguard Worker       if (src->interlaced) {
433*61046927SAndroid Build Coastguard Worker          /* Not 100% accurate, but close enough */
434*61046927SAndroid Build Coastguard Worker          switch (deinterlace) {
435*61046927SAndroid Build Coastguard Worker          case VL_COMPOSITOR_BOB_TOP:
436*61046927SAndroid Build Coastguard Worker             from = src_surfaces[i & ~1];
437*61046927SAndroid Build Coastguard Worker             break;
438*61046927SAndroid Build Coastguard Worker          case VL_COMPOSITOR_BOB_BOTTOM:
439*61046927SAndroid Build Coastguard Worker             from = src_surfaces[(i & ~1) + 1];
440*61046927SAndroid Build Coastguard Worker             break;
441*61046927SAndroid Build Coastguard Worker          default:
442*61046927SAndroid Build Coastguard Worker             break;
443*61046927SAndroid Build Coastguard Worker          }
444*61046927SAndroid Build Coastguard Worker       }
445*61046927SAndroid Build Coastguard Worker 
446*61046927SAndroid Build Coastguard Worker       if (!from || !dst_surfaces[i])
447*61046927SAndroid Build Coastguard Worker          continue;
448*61046927SAndroid Build Coastguard Worker 
449*61046927SAndroid Build Coastguard Worker       memset(&blit, 0, sizeof(blit));
450*61046927SAndroid Build Coastguard Worker       blit.src.resource = from->texture;
451*61046927SAndroid Build Coastguard Worker       blit.src.format = from->format;
452*61046927SAndroid Build Coastguard Worker       blit.src.level = 0;
453*61046927SAndroid Build Coastguard Worker       blit.src.box.z = from->u.tex.first_layer;
454*61046927SAndroid Build Coastguard Worker       blit.src.box.depth = 1;
455*61046927SAndroid Build Coastguard Worker       vlVaGetBox(src, i, &blit.src.box, src_region);
456*61046927SAndroid Build Coastguard Worker 
457*61046927SAndroid Build Coastguard Worker       blit.dst.resource = dst_surfaces[i]->texture;
458*61046927SAndroid Build Coastguard Worker       blit.dst.format = dst_surfaces[i]->format;
459*61046927SAndroid Build Coastguard Worker       blit.dst.level = 0;
460*61046927SAndroid Build Coastguard Worker       blit.dst.box.z = dst_surfaces[i]->u.tex.first_layer;
461*61046927SAndroid Build Coastguard Worker       blit.dst.box.depth = 1;
462*61046927SAndroid Build Coastguard Worker       vlVaGetBox(dst, i, &blit.dst.box, dst_region);
463*61046927SAndroid Build Coastguard Worker 
464*61046927SAndroid Build Coastguard Worker       blit.mask = PIPE_MASK_RGBA;
465*61046927SAndroid Build Coastguard Worker       blit.filter = PIPE_TEX_MIPFILTER_LINEAR;
466*61046927SAndroid Build Coastguard Worker 
467*61046927SAndroid Build Coastguard Worker       if (drv->pipe->screen->get_param(drv->pipe->screen,
468*61046927SAndroid Build Coastguard Worker                                        PIPE_CAP_PREFER_COMPUTE_FOR_MULTIMEDIA))
469*61046927SAndroid Build Coastguard Worker          util_compute_blit(drv->pipe, &blit, &context->blit_cs);
470*61046927SAndroid Build Coastguard Worker       else
471*61046927SAndroid Build Coastguard Worker          drv->pipe->blit(drv->pipe, &blit);
472*61046927SAndroid Build Coastguard Worker    }
473*61046927SAndroid Build Coastguard Worker 
474*61046927SAndroid Build Coastguard Worker    // TODO: figure out why this is necessary for DMA-buf sharing
475*61046927SAndroid Build Coastguard Worker    drv->pipe->flush(drv->pipe, NULL, 0);
476*61046927SAndroid Build Coastguard Worker 
477*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
478*61046927SAndroid Build Coastguard Worker }
479*61046927SAndroid Build Coastguard Worker 
480*61046927SAndroid Build Coastguard Worker static struct pipe_video_buffer *
vlVaApplyDeint(vlVaDriver * drv,vlVaContext * context,VAProcPipelineParameterBuffer * param,struct pipe_video_buffer * current,unsigned field)481*61046927SAndroid Build Coastguard Worker vlVaApplyDeint(vlVaDriver *drv, vlVaContext *context,
482*61046927SAndroid Build Coastguard Worker                VAProcPipelineParameterBuffer *param,
483*61046927SAndroid Build Coastguard Worker                struct pipe_video_buffer *current,
484*61046927SAndroid Build Coastguard Worker                unsigned field)
485*61046927SAndroid Build Coastguard Worker {
486*61046927SAndroid Build Coastguard Worker    vlVaSurface *prevprev, *prev, *next;
487*61046927SAndroid Build Coastguard Worker 
488*61046927SAndroid Build Coastguard Worker    if (param->num_forward_references < 2 ||
489*61046927SAndroid Build Coastguard Worker        param->num_backward_references < 1)
490*61046927SAndroid Build Coastguard Worker       return current;
491*61046927SAndroid Build Coastguard Worker 
492*61046927SAndroid Build Coastguard Worker    prevprev = handle_table_get(drv->htab, param->forward_references[1]);
493*61046927SAndroid Build Coastguard Worker    prev = handle_table_get(drv->htab, param->forward_references[0]);
494*61046927SAndroid Build Coastguard Worker    next = handle_table_get(drv->htab, param->backward_references[0]);
495*61046927SAndroid Build Coastguard Worker 
496*61046927SAndroid Build Coastguard Worker    if (!prevprev || !prev || !next)
497*61046927SAndroid Build Coastguard Worker       return current;
498*61046927SAndroid Build Coastguard Worker 
499*61046927SAndroid Build Coastguard Worker    if (context->deint && (context->deint->video_width != current->width ||
500*61046927SAndroid Build Coastguard Worker        context->deint->video_height != current->height ||
501*61046927SAndroid Build Coastguard Worker        context->deint->interleaved != !current->interlaced)) {
502*61046927SAndroid Build Coastguard Worker       vl_deint_filter_cleanup(context->deint);
503*61046927SAndroid Build Coastguard Worker       FREE(context->deint);
504*61046927SAndroid Build Coastguard Worker       context->deint = NULL;
505*61046927SAndroid Build Coastguard Worker    }
506*61046927SAndroid Build Coastguard Worker 
507*61046927SAndroid Build Coastguard Worker    if (!context->deint) {
508*61046927SAndroid Build Coastguard Worker       context->deint = MALLOC(sizeof(struct vl_deint_filter));
509*61046927SAndroid Build Coastguard Worker       if (!vl_deint_filter_init(context->deint, drv->pipe, current->width,
510*61046927SAndroid Build Coastguard Worker                                 current->height, false, false, !current->interlaced)) {
511*61046927SAndroid Build Coastguard Worker          FREE(context->deint);
512*61046927SAndroid Build Coastguard Worker          context->deint = NULL;
513*61046927SAndroid Build Coastguard Worker          return current;
514*61046927SAndroid Build Coastguard Worker       }
515*61046927SAndroid Build Coastguard Worker    }
516*61046927SAndroid Build Coastguard Worker 
517*61046927SAndroid Build Coastguard Worker    if (!vl_deint_filter_check_buffers(context->deint, prevprev->buffer,
518*61046927SAndroid Build Coastguard Worker                                       prev->buffer, current, next->buffer))
519*61046927SAndroid Build Coastguard Worker       return current;
520*61046927SAndroid Build Coastguard Worker 
521*61046927SAndroid Build Coastguard Worker    vl_deint_filter_render(context->deint, prevprev->buffer, prev->buffer,
522*61046927SAndroid Build Coastguard Worker                           current, next->buffer, field);
523*61046927SAndroid Build Coastguard Worker    return context->deint->video_buffer;
524*61046927SAndroid Build Coastguard Worker }
525*61046927SAndroid Build Coastguard Worker 
526*61046927SAndroid Build Coastguard Worker VAStatus
vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver * drv,vlVaContext * context,vlVaBuffer * buf)527*61046927SAndroid Build Coastguard Worker vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
528*61046927SAndroid Build Coastguard Worker {
529*61046927SAndroid Build Coastguard Worker    enum vl_compositor_deinterlace deinterlace = VL_COMPOSITOR_NONE;
530*61046927SAndroid Build Coastguard Worker    VARectangle def_src_region, def_dst_region;
531*61046927SAndroid Build Coastguard Worker    const VARectangle *src_region, *dst_region;
532*61046927SAndroid Build Coastguard Worker    VAProcPipelineParameterBuffer *param;
533*61046927SAndroid Build Coastguard Worker    struct pipe_video_buffer *src, *dst;
534*61046927SAndroid Build Coastguard Worker    vlVaSurface *src_surface, *dst_surface;
535*61046927SAndroid Build Coastguard Worker    unsigned i;
536*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen;
537*61046927SAndroid Build Coastguard Worker    VAStatus ret;
538*61046927SAndroid Build Coastguard Worker 
539*61046927SAndroid Build Coastguard Worker    if (!drv || !context)
540*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
541*61046927SAndroid Build Coastguard Worker 
542*61046927SAndroid Build Coastguard Worker    if (!buf || !buf->data)
543*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_BUFFER;
544*61046927SAndroid Build Coastguard Worker 
545*61046927SAndroid Build Coastguard Worker    if (!context->target)
546*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_SURFACE;
547*61046927SAndroid Build Coastguard Worker 
548*61046927SAndroid Build Coastguard Worker    param = buf->data;
549*61046927SAndroid Build Coastguard Worker 
550*61046927SAndroid Build Coastguard Worker    src_surface = handle_table_get(drv->htab, param->surface);
551*61046927SAndroid Build Coastguard Worker    dst_surface = handle_table_get(drv->htab, context->target_id);
552*61046927SAndroid Build Coastguard Worker    if (!src_surface || !dst_surface)
553*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_SURFACE;
554*61046927SAndroid Build Coastguard Worker    vlVaGetSurfaceBuffer(drv, src_surface);
555*61046927SAndroid Build Coastguard Worker    vlVaGetSurfaceBuffer(drv, dst_surface);
556*61046927SAndroid Build Coastguard Worker    if (!src_surface->buffer || !dst_surface->buffer)
557*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_SURFACE;
558*61046927SAndroid Build Coastguard Worker 
559*61046927SAndroid Build Coastguard Worker    src_surface->full_range = vlVaGetFullRange(src_surface,
560*61046927SAndroid Build Coastguard Worker       param->input_color_properties.color_range);
561*61046927SAndroid Build Coastguard Worker    dst_surface->full_range = vlVaGetFullRange(dst_surface,
562*61046927SAndroid Build Coastguard Worker       param->output_color_properties.color_range);
563*61046927SAndroid Build Coastguard Worker 
564*61046927SAndroid Build Coastguard Worker    pscreen = drv->vscreen->pscreen;
565*61046927SAndroid Build Coastguard Worker 
566*61046927SAndroid Build Coastguard Worker    src_region = vlVaRegionDefault(param->surface_region, src_surface, &def_src_region);
567*61046927SAndroid Build Coastguard Worker    dst_region = vlVaRegionDefault(param->output_region, dst_surface, &def_dst_region);
568*61046927SAndroid Build Coastguard Worker 
569*61046927SAndroid Build Coastguard Worker    /* EFC can only do one conversion, and it must be the last postproc
570*61046927SAndroid Build Coastguard Worker     * operation immediately before encoding.
571*61046927SAndroid Build Coastguard Worker     * Disable EFC completely if this is not the case. */
572*61046927SAndroid Build Coastguard Worker    if (drv->last_efc_surface) {
573*61046927SAndroid Build Coastguard Worker       vlVaSurface *surf = drv->last_efc_surface;
574*61046927SAndroid Build Coastguard Worker       surf->efc_surface = NULL;
575*61046927SAndroid Build Coastguard Worker       drv->last_efc_surface = NULL;
576*61046927SAndroid Build Coastguard Worker       drv->efc_count = -1;
577*61046927SAndroid Build Coastguard Worker    }
578*61046927SAndroid Build Coastguard Worker 
579*61046927SAndroid Build Coastguard Worker    if (drv->efc_count >= 0 && !param->num_filters &&
580*61046927SAndroid Build Coastguard Worker        src_region->width == dst_region->width &&
581*61046927SAndroid Build Coastguard Worker        src_region->height == dst_region->height &&
582*61046927SAndroid Build Coastguard Worker        src_region->x == dst_region->x &&
583*61046927SAndroid Build Coastguard Worker        src_region->y == dst_region->y &&
584*61046927SAndroid Build Coastguard Worker        pscreen->is_video_target_buffer_supported &&
585*61046927SAndroid Build Coastguard Worker        pscreen->is_video_target_buffer_supported(pscreen,
586*61046927SAndroid Build Coastguard Worker                                                  dst_surface->buffer->buffer_format,
587*61046927SAndroid Build Coastguard Worker                                                  src_surface->buffer,
588*61046927SAndroid Build Coastguard Worker                                                  PIPE_VIDEO_PROFILE_UNKNOWN,
589*61046927SAndroid Build Coastguard Worker                                                  PIPE_VIDEO_ENTRYPOINT_ENCODE)) {
590*61046927SAndroid Build Coastguard Worker 
591*61046927SAndroid Build Coastguard Worker       dst_surface->efc_surface = src_surface;
592*61046927SAndroid Build Coastguard Worker       drv->last_efc_surface = dst_surface;
593*61046927SAndroid Build Coastguard Worker 
594*61046927SAndroid Build Coastguard Worker       /* Do the blit for first few conversions as a fallback in case EFC
595*61046927SAndroid Build Coastguard Worker        * could not be used (see above), after that assume EFC can always
596*61046927SAndroid Build Coastguard Worker        * be used and skip the blit. */
597*61046927SAndroid Build Coastguard Worker       if (drv->efc_count < 16)
598*61046927SAndroid Build Coastguard Worker          drv->efc_count++;
599*61046927SAndroid Build Coastguard Worker       else
600*61046927SAndroid Build Coastguard Worker          return VA_STATUS_SUCCESS;
601*61046927SAndroid Build Coastguard Worker    }
602*61046927SAndroid Build Coastguard Worker 
603*61046927SAndroid Build Coastguard Worker    src = src_surface->buffer;
604*61046927SAndroid Build Coastguard Worker    dst = dst_surface->buffer;
605*61046927SAndroid Build Coastguard Worker 
606*61046927SAndroid Build Coastguard Worker    /* convert the destination buffer to progressive if we're deinterlacing
607*61046927SAndroid Build Coastguard Worker       otherwise we might end up deinterlacing twice */
608*61046927SAndroid Build Coastguard Worker    if (param->num_filters && dst->interlaced) {
609*61046927SAndroid Build Coastguard Worker       vlVaSurface *surf;
610*61046927SAndroid Build Coastguard Worker       surf = dst_surface;
611*61046927SAndroid Build Coastguard Worker       surf->templat.interlaced = false;
612*61046927SAndroid Build Coastguard Worker       dst->destroy(dst);
613*61046927SAndroid Build Coastguard Worker 
614*61046927SAndroid Build Coastguard Worker       if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS)
615*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_ALLOCATION_FAILED;
616*61046927SAndroid Build Coastguard Worker 
617*61046927SAndroid Build Coastguard Worker       dst = context->target = surf->buffer;
618*61046927SAndroid Build Coastguard Worker    }
619*61046927SAndroid Build Coastguard Worker 
620*61046927SAndroid Build Coastguard Worker    for (i = 0; i < param->num_filters; i++) {
621*61046927SAndroid Build Coastguard Worker       vlVaBuffer *buf = handle_table_get(drv->htab, param->filters[i]);
622*61046927SAndroid Build Coastguard Worker       VAProcFilterParameterBufferBase *filter;
623*61046927SAndroid Build Coastguard Worker 
624*61046927SAndroid Build Coastguard Worker       if (!buf || buf->type != VAProcFilterParameterBufferType)
625*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_INVALID_BUFFER;
626*61046927SAndroid Build Coastguard Worker 
627*61046927SAndroid Build Coastguard Worker       filter = buf->data;
628*61046927SAndroid Build Coastguard Worker       switch (filter->type) {
629*61046927SAndroid Build Coastguard Worker       case VAProcFilterDeinterlacing: {
630*61046927SAndroid Build Coastguard Worker          VAProcFilterParameterBufferDeinterlacing *deint = buf->data;
631*61046927SAndroid Build Coastguard Worker          switch (deint->algorithm) {
632*61046927SAndroid Build Coastguard Worker          case VAProcDeinterlacingBob:
633*61046927SAndroid Build Coastguard Worker             if (deint->flags & VA_DEINTERLACING_BOTTOM_FIELD)
634*61046927SAndroid Build Coastguard Worker                deinterlace = VL_COMPOSITOR_BOB_BOTTOM;
635*61046927SAndroid Build Coastguard Worker             else
636*61046927SAndroid Build Coastguard Worker                deinterlace = VL_COMPOSITOR_BOB_TOP;
637*61046927SAndroid Build Coastguard Worker             break;
638*61046927SAndroid Build Coastguard Worker 
639*61046927SAndroid Build Coastguard Worker          case VAProcDeinterlacingWeave:
640*61046927SAndroid Build Coastguard Worker             deinterlace = VL_COMPOSITOR_WEAVE;
641*61046927SAndroid Build Coastguard Worker             break;
642*61046927SAndroid Build Coastguard Worker 
643*61046927SAndroid Build Coastguard Worker          case VAProcDeinterlacingMotionAdaptive:
644*61046927SAndroid Build Coastguard Worker             src = vlVaApplyDeint(drv, context, param, src,
645*61046927SAndroid Build Coastguard Worker 				 !!(deint->flags & VA_DEINTERLACING_BOTTOM_FIELD));
646*61046927SAndroid Build Coastguard Worker              deinterlace = VL_COMPOSITOR_MOTION_ADAPTIVE;
647*61046927SAndroid Build Coastguard Worker             break;
648*61046927SAndroid Build Coastguard Worker 
649*61046927SAndroid Build Coastguard Worker          default:
650*61046927SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_UNIMPLEMENTED;
651*61046927SAndroid Build Coastguard Worker          }
652*61046927SAndroid Build Coastguard Worker          drv->compositor.deinterlace = deinterlace;
653*61046927SAndroid Build Coastguard Worker          break;
654*61046927SAndroid Build Coastguard Worker       }
655*61046927SAndroid Build Coastguard Worker 
656*61046927SAndroid Build Coastguard Worker       default:
657*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_UNIMPLEMENTED;
658*61046927SAndroid Build Coastguard Worker       }
659*61046927SAndroid Build Coastguard Worker    }
660*61046927SAndroid Build Coastguard Worker 
661*61046927SAndroid Build Coastguard Worker    /* If the driver supports video engine post proc, attempt to do that
662*61046927SAndroid Build Coastguard Worker     * if it fails, fallback to the other existing implementations below
663*61046927SAndroid Build Coastguard Worker     */
664*61046927SAndroid Build Coastguard Worker    if (pscreen->get_video_param(pscreen,
665*61046927SAndroid Build Coastguard Worker                                 PIPE_VIDEO_PROFILE_UNKNOWN,
666*61046927SAndroid Build Coastguard Worker                                 PIPE_VIDEO_ENTRYPOINT_PROCESSING,
667*61046927SAndroid Build Coastguard Worker                                 PIPE_VIDEO_CAP_SUPPORTED)) {
668*61046927SAndroid Build Coastguard Worker       if (!context->decoder) {
669*61046927SAndroid Build Coastguard Worker          context->decoder = drv->pipe->create_video_codec(drv->pipe, &context->templat);
670*61046927SAndroid Build Coastguard Worker          if (!context->decoder)
671*61046927SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_ALLOCATION_FAILED;
672*61046927SAndroid Build Coastguard Worker       }
673*61046927SAndroid Build Coastguard Worker 
674*61046927SAndroid Build Coastguard Worker       context->desc.vidproc.src_surface_fence = src_surface->fence;
675*61046927SAndroid Build Coastguard Worker       /* Perform VPBlit, if fail, fallback to other implementations below */
676*61046927SAndroid Build Coastguard Worker       if (VA_STATUS_SUCCESS == vlVaVidEngineBlit(drv, context, src_region, dst_region,
677*61046927SAndroid Build Coastguard Worker                                                  src, context->target, deinterlace, param))
678*61046927SAndroid Build Coastguard Worker          return VA_STATUS_SUCCESS;
679*61046927SAndroid Build Coastguard Worker    }
680*61046927SAndroid Build Coastguard Worker 
681*61046927SAndroid Build Coastguard Worker    /* Some devices may be media only (PIPE_VIDEO_ENTRYPOINT_PROCESSING with video engine)
682*61046927SAndroid Build Coastguard Worker     * and won't have shader support
683*61046927SAndroid Build Coastguard Worker     */
684*61046927SAndroid Build Coastguard Worker    if (!drv->vscreen->pscreen->get_param(drv->vscreen->pscreen, PIPE_CAP_GRAPHICS) &&
685*61046927SAndroid Build Coastguard Worker        !drv->vscreen->pscreen->get_param(drv->vscreen->pscreen, PIPE_CAP_COMPUTE))
686*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
687*61046927SAndroid Build Coastguard Worker 
688*61046927SAndroid Build Coastguard Worker    vlVaSetProcParameters(drv, src_surface, dst_surface, param);
689*61046927SAndroid Build Coastguard Worker 
690*61046927SAndroid Build Coastguard Worker    /* Try other post proc implementations */
691*61046927SAndroid Build Coastguard Worker    if (context->target->buffer_format != PIPE_FORMAT_NV12 &&
692*61046927SAndroid Build Coastguard Worker        context->target->buffer_format != PIPE_FORMAT_P010 &&
693*61046927SAndroid Build Coastguard Worker        context->target->buffer_format != PIPE_FORMAT_P016)
694*61046927SAndroid Build Coastguard Worker       ret = vlVaPostProcCompositor(drv, context, src_region, dst_region,
695*61046927SAndroid Build Coastguard Worker                                    src, context->target, deinterlace);
696*61046927SAndroid Build Coastguard Worker    else
697*61046927SAndroid Build Coastguard Worker       ret = vlVaPostProcBlit(drv, context, src_region, dst_region,
698*61046927SAndroid Build Coastguard Worker                              src, context->target, deinterlace);
699*61046927SAndroid Build Coastguard Worker 
700*61046927SAndroid Build Coastguard Worker    /* Reset chroma location */
701*61046927SAndroid Build Coastguard Worker    drv->cstate.chroma_location = VL_COMPOSITOR_LOCATION_NONE;
702*61046927SAndroid Build Coastguard Worker 
703*61046927SAndroid Build Coastguard Worker    return ret;
704*61046927SAndroid Build Coastguard Worker }
705