1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2015 Advanced Micro Devices, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "util/u_handle_table.h" 29bf215546Sopenharmony_ci#include "util/u_memory.h" 30bf215546Sopenharmony_ci#include "util/u_compute.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "vl/vl_defines.h" 33bf215546Sopenharmony_ci#include "vl/vl_video_buffer.h" 34bf215546Sopenharmony_ci#include "vl/vl_deint_filter.h" 35bf215546Sopenharmony_ci#include "vl/vl_winsys.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "va_private.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_cistatic const VARectangle * 40bf215546Sopenharmony_civlVaRegionDefault(const VARectangle *region, vlVaSurface *surf, 41bf215546Sopenharmony_ci VARectangle *def) 42bf215546Sopenharmony_ci{ 43bf215546Sopenharmony_ci if (region) 44bf215546Sopenharmony_ci return region; 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci def->x = 0; 47bf215546Sopenharmony_ci def->y = 0; 48bf215546Sopenharmony_ci def->width = surf->templat.width; 49bf215546Sopenharmony_ci def->height = surf->templat.height; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci return def; 52bf215546Sopenharmony_ci} 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_cistatic VAStatus 55bf215546Sopenharmony_civlVaPostProcCompositor(vlVaDriver *drv, vlVaContext *context, 56bf215546Sopenharmony_ci const VARectangle *src_region, 57bf215546Sopenharmony_ci const VARectangle *dst_region, 58bf215546Sopenharmony_ci struct pipe_video_buffer *src, 59bf215546Sopenharmony_ci struct pipe_video_buffer *dst, 60bf215546Sopenharmony_ci enum vl_compositor_deinterlace deinterlace) 61bf215546Sopenharmony_ci{ 62bf215546Sopenharmony_ci struct pipe_surface **surfaces; 63bf215546Sopenharmony_ci struct u_rect src_rect; 64bf215546Sopenharmony_ci struct u_rect dst_rect; 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci surfaces = dst->get_surfaces(dst); 67bf215546Sopenharmony_ci if (!surfaces || !surfaces[0]) 68bf215546Sopenharmony_ci return VA_STATUS_ERROR_INVALID_SURFACE; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci src_rect.x0 = src_region->x; 71bf215546Sopenharmony_ci src_rect.y0 = src_region->y; 72bf215546Sopenharmony_ci src_rect.x1 = src_region->x + src_region->width; 73bf215546Sopenharmony_ci src_rect.y1 = src_region->y + src_region->height; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci dst_rect.x0 = dst_region->x; 76bf215546Sopenharmony_ci dst_rect.y0 = dst_region->y; 77bf215546Sopenharmony_ci dst_rect.x1 = dst_region->x + dst_region->width; 78bf215546Sopenharmony_ci dst_rect.y1 = dst_region->y + dst_region->height; 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci vl_compositor_clear_layers(&drv->cstate); 81bf215546Sopenharmony_ci vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, src, 82bf215546Sopenharmony_ci &src_rect, NULL, deinterlace); 83bf215546Sopenharmony_ci vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dst_rect); 84bf215546Sopenharmony_ci vl_compositor_render(&drv->cstate, &drv->compositor, surfaces[0], NULL, false); 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci drv->pipe->flush(drv->pipe, NULL, 0); 87bf215546Sopenharmony_ci return VA_STATUS_SUCCESS; 88bf215546Sopenharmony_ci} 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_cistatic void vlVaGetBox(struct pipe_video_buffer *buf, unsigned idx, 91bf215546Sopenharmony_ci struct pipe_box *box, const VARectangle *region) 92bf215546Sopenharmony_ci{ 93bf215546Sopenharmony_ci unsigned plane = buf->interlaced ? idx / 2: idx; 94bf215546Sopenharmony_ci unsigned x, y, width, height; 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci x = abs(region->x); 97bf215546Sopenharmony_ci y = abs(region->y); 98bf215546Sopenharmony_ci width = region->width; 99bf215546Sopenharmony_ci height = region->height; 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci vl_video_buffer_adjust_size(&x, &y, plane, 102bf215546Sopenharmony_ci pipe_format_to_chroma_format(buf->buffer_format), 103bf215546Sopenharmony_ci buf->interlaced); 104bf215546Sopenharmony_ci vl_video_buffer_adjust_size(&width, &height, plane, 105bf215546Sopenharmony_ci pipe_format_to_chroma_format(buf->buffer_format), 106bf215546Sopenharmony_ci buf->interlaced); 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci box->x = region->x < 0 ? -x : x; 109bf215546Sopenharmony_ci box->y = region->y < 0 ? -y : y; 110bf215546Sopenharmony_ci box->width = width; 111bf215546Sopenharmony_ci box->height = height; 112bf215546Sopenharmony_ci} 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_cistatic VAStatus vlVaVidEngineBlit(vlVaDriver *drv, vlVaContext *context, 115bf215546Sopenharmony_ci const VARectangle *src_region, 116bf215546Sopenharmony_ci const VARectangle *dst_region, 117bf215546Sopenharmony_ci struct pipe_video_buffer *src, 118bf215546Sopenharmony_ci struct pipe_video_buffer *dst, 119bf215546Sopenharmony_ci enum vl_compositor_deinterlace deinterlace, 120bf215546Sopenharmony_ci VAProcPipelineParameterBuffer* param) 121bf215546Sopenharmony_ci{ 122bf215546Sopenharmony_ci if (deinterlace != VL_COMPOSITOR_NONE) 123bf215546Sopenharmony_ci return VA_STATUS_ERROR_UNIMPLEMENTED; 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci if (src->buffer_format != PIPE_FORMAT_NV12 || 126bf215546Sopenharmony_ci dst->buffer_format != PIPE_FORMAT_NV12) 127bf215546Sopenharmony_ci return VA_STATUS_ERROR_UNIMPLEMENTED; 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci struct u_rect src_rect; 130bf215546Sopenharmony_ci struct u_rect dst_rect; 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci src_rect.x0 = src_region->x; 133bf215546Sopenharmony_ci src_rect.y0 = src_region->y; 134bf215546Sopenharmony_ci src_rect.x1 = src_region->x + src_region->width; 135bf215546Sopenharmony_ci src_rect.y1 = src_region->y + src_region->height; 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci dst_rect.x0 = dst_region->x; 138bf215546Sopenharmony_ci dst_rect.y0 = dst_region->y; 139bf215546Sopenharmony_ci dst_rect.x1 = dst_region->x + dst_region->width; 140bf215546Sopenharmony_ci dst_rect.y1 = dst_region->y + dst_region->height; 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci context->desc.vidproc.base.input_format = src->buffer_format; 143bf215546Sopenharmony_ci context->desc.vidproc.base.output_format = dst->buffer_format; 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci context->desc.vidproc.src_region = src_rect; 146bf215546Sopenharmony_ci context->desc.vidproc.dst_region = dst_rect; 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci if (param->rotation_state == VA_ROTATION_NONE) 149bf215546Sopenharmony_ci context->desc.vidproc.orientation = PIPE_VIDEO_VPP_ORIENTATION_DEFAULT; 150bf215546Sopenharmony_ci else if (param->rotation_state == VA_ROTATION_90) 151bf215546Sopenharmony_ci context->desc.vidproc.orientation = PIPE_VIDEO_VPP_ROTATION_90; 152bf215546Sopenharmony_ci else if (param->rotation_state == VA_ROTATION_180) 153bf215546Sopenharmony_ci context->desc.vidproc.orientation = PIPE_VIDEO_VPP_ROTATION_180; 154bf215546Sopenharmony_ci else if (param->rotation_state == VA_ROTATION_270) 155bf215546Sopenharmony_ci context->desc.vidproc.orientation = PIPE_VIDEO_VPP_ROTATION_270; 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci if (param->mirror_state == VA_MIRROR_HORIZONTAL) 158bf215546Sopenharmony_ci context->desc.vidproc.orientation |= PIPE_VIDEO_VPP_FLIP_HORIZONTAL; 159bf215546Sopenharmony_ci if (param->mirror_state == VA_MIRROR_VERTICAL) 160bf215546Sopenharmony_ci context->desc.vidproc.orientation |= PIPE_VIDEO_VPP_FLIP_VERTICAL; 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci memset(&context->desc.vidproc.blend, 0, sizeof(context->desc.vidproc.blend)); 163bf215546Sopenharmony_ci context->desc.vidproc.blend.mode = PIPE_VIDEO_VPP_BLEND_MODE_NONE; 164bf215546Sopenharmony_ci if (param->blend_state != NULL) { 165bf215546Sopenharmony_ci if (param->blend_state->flags & VA_BLEND_GLOBAL_ALPHA) { 166bf215546Sopenharmony_ci context->desc.vidproc.blend.mode = PIPE_VIDEO_VPP_BLEND_MODE_GLOBAL_ALPHA; 167bf215546Sopenharmony_ci context->desc.vidproc.blend.global_alpha = param->blend_state->global_alpha; 168bf215546Sopenharmony_ci } 169bf215546Sopenharmony_ci } 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci if (context->needs_begin_frame) { 172bf215546Sopenharmony_ci context->decoder->begin_frame(context->decoder, dst, 173bf215546Sopenharmony_ci &context->desc.base); 174bf215546Sopenharmony_ci context->needs_begin_frame = false; 175bf215546Sopenharmony_ci } 176bf215546Sopenharmony_ci context->decoder->process_frame(context->decoder, src, &context->desc.vidproc); 177bf215546Sopenharmony_ci context->vpp_needs_flush_on_endpic = true; 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci return VA_STATUS_SUCCESS; 180bf215546Sopenharmony_ci} 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_cistatic VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, 183bf215546Sopenharmony_ci const VARectangle *src_region, 184bf215546Sopenharmony_ci const VARectangle *dst_region, 185bf215546Sopenharmony_ci struct pipe_video_buffer *src, 186bf215546Sopenharmony_ci struct pipe_video_buffer *dst, 187bf215546Sopenharmony_ci enum vl_compositor_deinterlace deinterlace) 188bf215546Sopenharmony_ci{ 189bf215546Sopenharmony_ci struct pipe_surface **src_surfaces; 190bf215546Sopenharmony_ci struct pipe_surface **dst_surfaces; 191bf215546Sopenharmony_ci struct u_rect src_rect; 192bf215546Sopenharmony_ci struct u_rect dst_rect; 193bf215546Sopenharmony_ci bool scale = false; 194bf215546Sopenharmony_ci bool grab = false; 195bf215546Sopenharmony_ci unsigned i; 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci if ((src->buffer_format == PIPE_FORMAT_B8G8R8X8_UNORM || 198bf215546Sopenharmony_ci src->buffer_format == PIPE_FORMAT_B8G8R8A8_UNORM || 199bf215546Sopenharmony_ci src->buffer_format == PIPE_FORMAT_R8G8B8X8_UNORM || 200bf215546Sopenharmony_ci src->buffer_format == PIPE_FORMAT_R8G8B8A8_UNORM) && 201bf215546Sopenharmony_ci !src->interlaced) 202bf215546Sopenharmony_ci grab = true; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci if ((src->width != dst->width || src->height != dst->height) && 205bf215546Sopenharmony_ci (src->interlaced && dst->interlaced)) 206bf215546Sopenharmony_ci scale = true; 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci src_surfaces = src->get_surfaces(src); 209bf215546Sopenharmony_ci if (!src_surfaces || !src_surfaces[0]) 210bf215546Sopenharmony_ci return VA_STATUS_ERROR_INVALID_SURFACE; 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci if (scale || (src->interlaced != dst->interlaced && dst->interlaced)) { 213bf215546Sopenharmony_ci vlVaSurface *surf; 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci surf = handle_table_get(drv->htab, context->target_id); 216bf215546Sopenharmony_ci surf->templat.interlaced = false; 217bf215546Sopenharmony_ci dst->destroy(dst); 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) 220bf215546Sopenharmony_ci return VA_STATUS_ERROR_ALLOCATION_FAILED; 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci dst = context->target = surf->buffer; 223bf215546Sopenharmony_ci } 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci dst_surfaces = dst->get_surfaces(dst); 226bf215546Sopenharmony_ci if (!dst_surfaces || !dst_surfaces[0]) 227bf215546Sopenharmony_ci return VA_STATUS_ERROR_INVALID_SURFACE; 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci src_rect.x0 = src_region->x; 230bf215546Sopenharmony_ci src_rect.y0 = src_region->y; 231bf215546Sopenharmony_ci src_rect.x1 = src_region->x + src_region->width; 232bf215546Sopenharmony_ci src_rect.y1 = src_region->y + src_region->height; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci dst_rect.x0 = dst_region->x; 235bf215546Sopenharmony_ci dst_rect.y0 = dst_region->y; 236bf215546Sopenharmony_ci dst_rect.x1 = dst_region->x + dst_region->width; 237bf215546Sopenharmony_ci dst_rect.y1 = dst_region->y + dst_region->height; 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci if (grab) { 240bf215546Sopenharmony_ci vl_compositor_convert_rgb_to_yuv(&drv->cstate, &drv->compositor, 0, 241bf215546Sopenharmony_ci ((struct vl_video_buffer *)src)->resources[0], 242bf215546Sopenharmony_ci dst, &src_rect, &dst_rect); 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci return VA_STATUS_SUCCESS; 245bf215546Sopenharmony_ci } 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci if (src->interlaced != dst->interlaced) { 248bf215546Sopenharmony_ci vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor, 249bf215546Sopenharmony_ci src, dst, &src_rect, &dst_rect, 250bf215546Sopenharmony_ci deinterlace); 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci return VA_STATUS_SUCCESS; 253bf215546Sopenharmony_ci } 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci for (i = 0; i < VL_MAX_SURFACES; ++i) { 256bf215546Sopenharmony_ci struct pipe_surface *from = src_surfaces[i]; 257bf215546Sopenharmony_ci struct pipe_blit_info blit; 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci if (src->interlaced) { 260bf215546Sopenharmony_ci /* Not 100% accurate, but close enough */ 261bf215546Sopenharmony_ci switch (deinterlace) { 262bf215546Sopenharmony_ci case VL_COMPOSITOR_BOB_TOP: 263bf215546Sopenharmony_ci from = src_surfaces[i & ~1]; 264bf215546Sopenharmony_ci break; 265bf215546Sopenharmony_ci case VL_COMPOSITOR_BOB_BOTTOM: 266bf215546Sopenharmony_ci from = src_surfaces[(i & ~1) + 1]; 267bf215546Sopenharmony_ci break; 268bf215546Sopenharmony_ci default: 269bf215546Sopenharmony_ci break; 270bf215546Sopenharmony_ci } 271bf215546Sopenharmony_ci } 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci if (!from || !dst_surfaces[i]) 274bf215546Sopenharmony_ci continue; 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci memset(&blit, 0, sizeof(blit)); 277bf215546Sopenharmony_ci blit.src.resource = from->texture; 278bf215546Sopenharmony_ci blit.src.format = from->format; 279bf215546Sopenharmony_ci blit.src.level = 0; 280bf215546Sopenharmony_ci blit.src.box.z = from->u.tex.first_layer; 281bf215546Sopenharmony_ci blit.src.box.depth = 1; 282bf215546Sopenharmony_ci vlVaGetBox(src, i, &blit.src.box, src_region); 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci blit.dst.resource = dst_surfaces[i]->texture; 285bf215546Sopenharmony_ci blit.dst.format = dst_surfaces[i]->format; 286bf215546Sopenharmony_ci blit.dst.level = 0; 287bf215546Sopenharmony_ci blit.dst.box.z = dst_surfaces[i]->u.tex.first_layer; 288bf215546Sopenharmony_ci blit.dst.box.depth = 1; 289bf215546Sopenharmony_ci vlVaGetBox(dst, i, &blit.dst.box, dst_region); 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci blit.mask = PIPE_MASK_RGBA; 292bf215546Sopenharmony_ci blit.filter = PIPE_TEX_MIPFILTER_LINEAR; 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci if (drv->pipe->screen->get_param(drv->pipe->screen, 295bf215546Sopenharmony_ci PIPE_CAP_PREFER_COMPUTE_FOR_MULTIMEDIA)) 296bf215546Sopenharmony_ci util_compute_blit(drv->pipe, &blit, &context->blit_cs, !drv->compositor.deinterlace); 297bf215546Sopenharmony_ci else 298bf215546Sopenharmony_ci drv->pipe->blit(drv->pipe, &blit); 299bf215546Sopenharmony_ci } 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci // TODO: figure out why this is necessary for DMA-buf sharing 302bf215546Sopenharmony_ci drv->pipe->flush(drv->pipe, NULL, 0); 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci return VA_STATUS_SUCCESS; 305bf215546Sopenharmony_ci} 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_cistatic struct pipe_video_buffer * 308bf215546Sopenharmony_civlVaApplyDeint(vlVaDriver *drv, vlVaContext *context, 309bf215546Sopenharmony_ci VAProcPipelineParameterBuffer *param, 310bf215546Sopenharmony_ci struct pipe_video_buffer *current, 311bf215546Sopenharmony_ci unsigned field) 312bf215546Sopenharmony_ci{ 313bf215546Sopenharmony_ci vlVaSurface *prevprev, *prev, *next; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci if (param->num_forward_references < 2 || 316bf215546Sopenharmony_ci param->num_backward_references < 1) 317bf215546Sopenharmony_ci return current; 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci prevprev = handle_table_get(drv->htab, param->forward_references[1]); 320bf215546Sopenharmony_ci prev = handle_table_get(drv->htab, param->forward_references[0]); 321bf215546Sopenharmony_ci next = handle_table_get(drv->htab, param->backward_references[0]); 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci if (!prevprev || !prev || !next) 324bf215546Sopenharmony_ci return current; 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci if (context->deint && (context->deint->video_width != current->width || 327bf215546Sopenharmony_ci context->deint->video_height != current->height)) { 328bf215546Sopenharmony_ci vl_deint_filter_cleanup(context->deint); 329bf215546Sopenharmony_ci FREE(context->deint); 330bf215546Sopenharmony_ci context->deint = NULL; 331bf215546Sopenharmony_ci } 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci if (!context->deint) { 334bf215546Sopenharmony_ci context->deint = MALLOC(sizeof(struct vl_deint_filter)); 335bf215546Sopenharmony_ci if (!vl_deint_filter_init(context->deint, drv->pipe, current->width, 336bf215546Sopenharmony_ci current->height, false, false)) { 337bf215546Sopenharmony_ci FREE(context->deint); 338bf215546Sopenharmony_ci context->deint = NULL; 339bf215546Sopenharmony_ci return current; 340bf215546Sopenharmony_ci } 341bf215546Sopenharmony_ci } 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci if (!vl_deint_filter_check_buffers(context->deint, prevprev->buffer, 344bf215546Sopenharmony_ci prev->buffer, current, next->buffer)) 345bf215546Sopenharmony_ci return current; 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci vl_deint_filter_render(context->deint, prevprev->buffer, prev->buffer, 348bf215546Sopenharmony_ci current, next->buffer, field); 349bf215546Sopenharmony_ci return context->deint->video_buffer; 350bf215546Sopenharmony_ci} 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ciVAStatus 353bf215546Sopenharmony_civlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) 354bf215546Sopenharmony_ci{ 355bf215546Sopenharmony_ci enum vl_compositor_deinterlace deinterlace = VL_COMPOSITOR_NONE; 356bf215546Sopenharmony_ci VARectangle def_src_region, def_dst_region; 357bf215546Sopenharmony_ci const VARectangle *src_region, *dst_region; 358bf215546Sopenharmony_ci VAProcPipelineParameterBuffer *param; 359bf215546Sopenharmony_ci struct pipe_video_buffer *src, *dst; 360bf215546Sopenharmony_ci vlVaSurface *src_surface, *dst_surface; 361bf215546Sopenharmony_ci unsigned i; 362bf215546Sopenharmony_ci struct pipe_screen *pscreen; 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci if (!drv || !context) 365bf215546Sopenharmony_ci return VA_STATUS_ERROR_INVALID_CONTEXT; 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci if (!buf || !buf->data) 368bf215546Sopenharmony_ci return VA_STATUS_ERROR_INVALID_BUFFER; 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci if (!context->target) 371bf215546Sopenharmony_ci return VA_STATUS_ERROR_INVALID_SURFACE; 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci param = buf->data; 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci src_surface = handle_table_get(drv->htab, param->surface); 376bf215546Sopenharmony_ci dst_surface = handle_table_get(drv->htab, context->target_id); 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci pscreen = drv->vscreen->pscreen; 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci if (src_surface->buffer->buffer_format != dst_surface->buffer->buffer_format && 381bf215546Sopenharmony_ci !src_surface->buffer->interlaced && 382bf215546Sopenharmony_ci (dst_surface->buffer->buffer_format == PIPE_FORMAT_NV12 || 383bf215546Sopenharmony_ci dst_surface->buffer->buffer_format == PIPE_FORMAT_P010 || 384bf215546Sopenharmony_ci dst_surface->buffer->buffer_format == PIPE_FORMAT_P016) && 385bf215546Sopenharmony_ci pscreen->get_video_param(pscreen, 386bf215546Sopenharmony_ci PIPE_VIDEO_PROFILE_UNKNOWN, 387bf215546Sopenharmony_ci PIPE_VIDEO_ENTRYPOINT_ENCODE, 388bf215546Sopenharmony_ci PIPE_VIDEO_CAP_EFC_SUPPORTED)) { 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci // EFC will convert the buffer to a format the encoder accepts 391bf215546Sopenharmony_ci dst_surface->encoder_format = dst_surface->buffer->buffer_format; 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci vlVaSurface *surf; 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci surf = handle_table_get(drv->htab, context->target_id); 396bf215546Sopenharmony_ci surf->templat.interlaced = src_surface->templat.interlaced; 397bf215546Sopenharmony_ci surf->templat.buffer_format = src_surface->templat.buffer_format; 398bf215546Sopenharmony_ci surf->buffer->destroy(surf->buffer); 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) 401bf215546Sopenharmony_ci return VA_STATUS_ERROR_ALLOCATION_FAILED; 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci pipe_resource_reference(&(((struct vl_video_buffer *)(surf->buffer))->resources[0]), ((struct vl_video_buffer *)(src_surface->buffer))->resources[0]); 404bf215546Sopenharmony_ci context->target = surf->buffer; 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ci return VA_STATUS_SUCCESS; 407bf215546Sopenharmony_ci } 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci if (!src_surface || !src_surface->buffer) 410bf215546Sopenharmony_ci return VA_STATUS_ERROR_INVALID_SURFACE; 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci src = src_surface->buffer; 413bf215546Sopenharmony_ci dst = dst_surface->buffer; 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci /* convert the destination buffer to progressive if we're deinterlacing 416bf215546Sopenharmony_ci otherwise we might end up deinterlacing twice */ 417bf215546Sopenharmony_ci if (param->num_filters && dst->interlaced) { 418bf215546Sopenharmony_ci vlVaSurface *surf; 419bf215546Sopenharmony_ci surf = dst_surface; 420bf215546Sopenharmony_ci surf->templat.interlaced = false; 421bf215546Sopenharmony_ci dst->destroy(dst); 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) 424bf215546Sopenharmony_ci return VA_STATUS_ERROR_ALLOCATION_FAILED; 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci dst = context->target = surf->buffer; 427bf215546Sopenharmony_ci } 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci for (i = 0; i < param->num_filters; i++) { 430bf215546Sopenharmony_ci vlVaBuffer *buf = handle_table_get(drv->htab, param->filters[i]); 431bf215546Sopenharmony_ci VAProcFilterParameterBufferBase *filter; 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci if (!buf || buf->type != VAProcFilterParameterBufferType) 434bf215546Sopenharmony_ci return VA_STATUS_ERROR_INVALID_BUFFER; 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci filter = buf->data; 437bf215546Sopenharmony_ci switch (filter->type) { 438bf215546Sopenharmony_ci case VAProcFilterDeinterlacing: { 439bf215546Sopenharmony_ci VAProcFilterParameterBufferDeinterlacing *deint = buf->data; 440bf215546Sopenharmony_ci switch (deint->algorithm) { 441bf215546Sopenharmony_ci case VAProcDeinterlacingBob: 442bf215546Sopenharmony_ci if (deint->flags & VA_DEINTERLACING_BOTTOM_FIELD) 443bf215546Sopenharmony_ci deinterlace = VL_COMPOSITOR_BOB_BOTTOM; 444bf215546Sopenharmony_ci else 445bf215546Sopenharmony_ci deinterlace = VL_COMPOSITOR_BOB_TOP; 446bf215546Sopenharmony_ci break; 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_ci case VAProcDeinterlacingWeave: 449bf215546Sopenharmony_ci deinterlace = VL_COMPOSITOR_WEAVE; 450bf215546Sopenharmony_ci break; 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci case VAProcDeinterlacingMotionAdaptive: 453bf215546Sopenharmony_ci src = vlVaApplyDeint(drv, context, param, src, 454bf215546Sopenharmony_ci !!(deint->flags & VA_DEINTERLACING_BOTTOM_FIELD)); 455bf215546Sopenharmony_ci deinterlace = VL_COMPOSITOR_MOTION_ADAPTIVE; 456bf215546Sopenharmony_ci break; 457bf215546Sopenharmony_ci 458bf215546Sopenharmony_ci default: 459bf215546Sopenharmony_ci return VA_STATUS_ERROR_UNIMPLEMENTED; 460bf215546Sopenharmony_ci } 461bf215546Sopenharmony_ci drv->compositor.deinterlace = deinterlace; 462bf215546Sopenharmony_ci break; 463bf215546Sopenharmony_ci } 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_ci default: 466bf215546Sopenharmony_ci return VA_STATUS_ERROR_UNIMPLEMENTED; 467bf215546Sopenharmony_ci } 468bf215546Sopenharmony_ci } 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci src_region = vlVaRegionDefault(param->surface_region, src_surface, &def_src_region); 471bf215546Sopenharmony_ci dst_region = vlVaRegionDefault(param->output_region, dst_surface, &def_dst_region); 472bf215546Sopenharmony_ci 473bf215546Sopenharmony_ci /* If the driver supports video engine post proc, attempt to do that 474bf215546Sopenharmony_ci * if it fails, fallback to the other existing implementations below 475bf215546Sopenharmony_ci */ 476bf215546Sopenharmony_ci if (pscreen->get_video_param(pscreen, 477bf215546Sopenharmony_ci PIPE_VIDEO_PROFILE_UNKNOWN, 478bf215546Sopenharmony_ci PIPE_VIDEO_ENTRYPOINT_PROCESSING, 479bf215546Sopenharmony_ci PIPE_VIDEO_CAP_SUPPORTED)) { 480bf215546Sopenharmony_ci if (!context->decoder) { 481bf215546Sopenharmony_ci context->decoder = drv->pipe->create_video_codec(drv->pipe, &context->templat); 482bf215546Sopenharmony_ci if (!context->decoder) 483bf215546Sopenharmony_ci return VA_STATUS_ERROR_ALLOCATION_FAILED; 484bf215546Sopenharmony_ci } 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci /* Perform VPBlit, if fail, fallback to other implementations below */ 487bf215546Sopenharmony_ci if (VA_STATUS_SUCCESS == vlVaVidEngineBlit(drv, context, src_region, dst_region, 488bf215546Sopenharmony_ci src, context->target, deinterlace, param)) 489bf215546Sopenharmony_ci return VA_STATUS_SUCCESS; 490bf215546Sopenharmony_ci } 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci /* Try other post proc implementations */ 493bf215546Sopenharmony_ci if (context->target->buffer_format != PIPE_FORMAT_NV12 && 494bf215546Sopenharmony_ci context->target->buffer_format != PIPE_FORMAT_P010 && 495bf215546Sopenharmony_ci context->target->buffer_format != PIPE_FORMAT_P016) 496bf215546Sopenharmony_ci return vlVaPostProcCompositor(drv, context, src_region, dst_region, 497bf215546Sopenharmony_ci src, context->target, deinterlace); 498bf215546Sopenharmony_ci else 499bf215546Sopenharmony_ci return vlVaPostProcBlit(drv, context, src_region, dst_region, 500bf215546Sopenharmony_ci src, context->target, deinterlace); 501bf215546Sopenharmony_ci} 502