2 * Copyright © 2011 Intel Corporation
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
25 * Li Xiaowei <xiaowei.a.li@intel.com>
33 #include "intel_batchbuffer.h"
34 #include "intel_driver.h"
35 #include "i965_defines.h"
36 #include "i965_structs.h"
38 #include "i965_drv_video.h"
39 #include "i965_post_processing.h"
40 #include "gen75_picture_process.h"
42 extern struct hw_context *
43 i965_proc_context_init(VADriverContextP ctx,
44 struct object_config *obj_config);
47 gen75_vpp_fmt_cvt(VADriverContextP ctx,
49 union codec_state *codec_state,
50 struct hw_context *hw_context)
52 VAStatus va_status = VA_STATUS_SUCCESS;
53 struct intel_video_process_context *proc_ctx =
54 (struct intel_video_process_context *)hw_context;
56 /* implicity surface format coversion and scaling */
57 if(proc_ctx->vpp_fmt_cvt_ctx == NULL){
58 proc_ctx->vpp_fmt_cvt_ctx = i965_proc_context_init(ctx, NULL);
61 va_status = i965_proc_picture(ctx, profile, codec_state,
62 proc_ctx->vpp_fmt_cvt_ctx);
68 gen75_vpp_vebox(VADriverContextP ctx,
69 struct intel_video_process_context* proc_ctx)
71 VAStatus va_status = VA_STATUS_SUCCESS;
72 VAProcPipelineParameterBuffer* pipeline_param = proc_ctx->pipeline_param;
73 struct i965_driver_data *i965 = i965_driver_data(ctx);
75 /* vpp features based on VEBox fixed function */
76 if(proc_ctx->vpp_vebox_ctx == NULL) {
77 proc_ctx->vpp_vebox_ctx = gen75_vebox_context_init(ctx);
80 proc_ctx->vpp_vebox_ctx->pipeline_param = pipeline_param;
81 proc_ctx->vpp_vebox_ctx->surface_input_object = proc_ctx->surface_pipeline_input_object;
82 proc_ctx->vpp_vebox_ctx->surface_output_object = proc_ctx->surface_render_output_object;
84 if (IS_HASWELL(i965->intel.device_info))
85 va_status = gen75_vebox_process_picture(ctx, proc_ctx->vpp_vebox_ctx);
86 else if (IS_GEN8(i965->intel.device_info))
87 va_status = gen8_vebox_process_picture(ctx, proc_ctx->vpp_vebox_ctx);
88 else if (IS_GEN9(i965->intel.device_info))
89 va_status = gen9_vebox_process_picture(ctx, proc_ctx->vpp_vebox_ctx);
95 gen75_proc_picture(VADriverContextP ctx,
97 union codec_state *codec_state,
98 struct hw_context *hw_context)
100 struct i965_driver_data *i965 = i965_driver_data(ctx);
101 struct proc_state* proc_st = &(codec_state->proc);
102 struct intel_video_process_context *proc_ctx =
103 (struct intel_video_process_context *)hw_context;
104 VAProcPipelineParameterBuffer *pipeline_param =
105 (VAProcPipelineParameterBuffer *)proc_st->pipeline_param->buffer;
106 struct object_surface *obj_dst_surf = NULL;
107 struct object_surface *obj_src_surf = NULL;
109 VAProcPipelineParameterBuffer pipeline_param2;
110 struct object_surface *stage1_dst_surf = NULL;
111 struct object_surface *stage2_dst_surf = NULL;
112 VARectangle src_rect, dst_rect;
113 VASurfaceID tmp_surfaces[2];
114 VASurfaceID out_surface_id1 = VA_INVALID_ID, out_surface_id2 = VA_INVALID_ID;
115 int num_tmp_surfaces = 0;
119 proc_ctx->pipeline_param = pipeline_param;
121 if (proc_st->current_render_target == VA_INVALID_SURFACE ||
122 pipeline_param->surface == VA_INVALID_SURFACE) {
123 status = VA_STATUS_ERROR_INVALID_SURFACE;
127 obj_dst_surf = SURFACE(proc_st->current_render_target);
130 status = VA_STATUS_ERROR_INVALID_SURFACE;
134 obj_src_surf = SURFACE(proc_ctx->pipeline_param->surface);
137 status = VA_STATUS_ERROR_INVALID_SURFACE;
141 if (!obj_src_surf->bo) {
142 status = VA_STATUS_ERROR_INVALID_VALUE; /* The input surface is created without valid content */
146 if (pipeline_param->num_filters && !pipeline_param->filters) {
147 status = VA_STATUS_ERROR_INVALID_PARAMETER;
151 if (!obj_dst_surf->bo) {
152 unsigned int is_tiled = 1;
153 unsigned int fourcc = VA_FOURCC_NV12;
154 int sampling = SUBSAMPLE_YUV420;
155 i965_check_alloc_surface_bo(ctx, obj_dst_surf, is_tiled, fourcc, sampling);
158 proc_ctx->surface_render_output_object = obj_dst_surf;
159 proc_ctx->surface_pipeline_input_object = obj_src_surf;
160 assert(pipeline_param->num_filters <= 4);
162 int vpp_stage1 = 0, vpp_stage2 = 1, vpp_stage3 = 0;
164 if (pipeline_param->surface_region) {
165 src_rect.x = pipeline_param->surface_region->x;
166 src_rect.y = pipeline_param->surface_region->y;
167 src_rect.width = pipeline_param->surface_region->width;
168 src_rect.height = pipeline_param->surface_region->height;
172 src_rect.width = obj_src_surf->orig_width;
173 src_rect.height = obj_src_surf->orig_height;
176 if (pipeline_param->output_region) {
177 dst_rect.x = pipeline_param->output_region->x;
178 dst_rect.y = pipeline_param->output_region->y;
179 dst_rect.width = pipeline_param->output_region->width;
180 dst_rect.height = pipeline_param->output_region->height;
184 dst_rect.width = obj_dst_surf->orig_width;
185 dst_rect.height = obj_dst_surf->orig_height;
188 if(obj_src_surf->fourcc == VA_FOURCC_P010) {
192 if(pipeline_param->num_filters == 0 || pipeline_param->filters == NULL) {
193 if(src_rect.x != dst_rect.x ||
194 src_rect.y != dst_rect.y ||
195 src_rect.width != dst_rect.width ||
196 src_rect.height != dst_rect.height)
199 if(obj_dst_surf->fourcc != VA_FOURCC_NV12 &&
200 obj_dst_surf->fourcc != VA_FOURCC_P010)
206 if(vpp_stage2 == 1) {
207 if(obj_dst_surf->fourcc == VA_FOURCC_P010)
211 else if(obj_dst_surf->fourcc == VA_FOURCC_P010) {
215 if((obj_src_surf->fourcc == VA_FOURCC_NV12) &&
216 (pipeline_param->num_filters == 0 || pipeline_param->filters == NULL)) {
217 if((src_rect.x == dst_rect.x) &&
218 (src_rect.y == dst_rect.y) &&
219 (src_rect.width == dst_rect.width) &&
220 (src_rect.height == dst_rect.height))
226 memset((void *)&pipeline_param2, 0, sizeof(pipeline_param2));
227 pipeline_param2.surface = pipeline_param->surface;
228 pipeline_param2.surface_region = &src_rect;
229 pipeline_param2.output_region = &src_rect;
230 pipeline_param2.filter_flags = 0;
231 pipeline_param2.num_filters = 0;
233 proc_ctx->pipeline_param = &pipeline_param2;
235 if(vpp_stage2 == 1) {
236 status = i965_CreateSurfaces(ctx,
237 obj_src_surf->orig_width,
238 obj_src_surf->orig_height,
242 assert(status == VA_STATUS_SUCCESS);
243 tmp_surfaces[num_tmp_surfaces++] = out_surface_id1;
244 stage1_dst_surf = SURFACE(out_surface_id1);
245 assert(stage1_dst_surf);
246 i965_check_alloc_surface_bo(ctx, stage1_dst_surf, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
248 proc_ctx->surface_render_output_object = stage1_dst_surf;
251 gen75_vpp_vebox(ctx, proc_ctx);
254 if((vpp_stage3 == 1) && (vpp_stage2 == 1)) {
255 status = i965_CreateSurfaces(ctx,
256 obj_dst_surf->orig_width,
257 obj_dst_surf->orig_height,
261 assert(status == VA_STATUS_SUCCESS);
262 tmp_surfaces[num_tmp_surfaces++] = out_surface_id2;
263 stage2_dst_surf = SURFACE(out_surface_id2);
264 assert(stage2_dst_surf);
265 i965_check_alloc_surface_bo(ctx, stage2_dst_surf, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
268 VABufferID *filter_id = (VABufferID*) pipeline_param->filters;
270 if(vpp_stage2 == 1) {
271 if(stage1_dst_surf != NULL) {
272 proc_ctx->surface_pipeline_input_object = stage1_dst_surf;
273 proc_ctx->surface_render_output_object = obj_dst_surf;
275 pipeline_param->surface = out_surface_id1;
278 if(stage2_dst_surf != NULL) {
279 proc_ctx->surface_render_output_object = stage2_dst_surf;
281 proc_st->current_render_target = out_surface_id2;
284 proc_ctx->pipeline_param = pipeline_param;
286 if(pipeline_param->num_filters == 0 || pipeline_param->filters == NULL ){
287 /* implicity surface format coversion and scaling */
289 gen75_vpp_fmt_cvt(ctx, profile, codec_state, hw_context);
290 }else if(pipeline_param->num_filters == 1) {
291 struct object_buffer * obj_buf = BUFFER((*filter_id) + 0);
293 assert(obj_buf && obj_buf->buffer_store && obj_buf->buffer_store->buffer);
296 !obj_buf->buffer_store ||
297 !obj_buf->buffer_store->buffer) {
298 status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
302 VAProcFilterParameterBuffer* filter =
303 (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
305 if (filter->type == VAProcFilterNoiseReduction ||
306 filter->type == VAProcFilterDeinterlacing ||
307 filter->type == VAProcFilterSkinToneEnhancement ||
308 filter->type == VAProcFilterSharpening ||
309 filter->type == VAProcFilterColorBalance){
310 gen75_vpp_vebox(ctx, proc_ctx);
312 }else if (pipeline_param->num_filters >= 2) {
314 for (i = 0; i < pipeline_param->num_filters; i++){
315 struct object_buffer * obj_buf = BUFFER(pipeline_param->filters[i]);
318 !obj_buf->buffer_store ||
319 !obj_buf->buffer_store->buffer) {
320 status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
324 VAProcFilterParameterBuffer* filter =
325 (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
327 if (filter->type != VAProcFilterNoiseReduction &&
328 filter->type != VAProcFilterDeinterlacing &&
329 filter->type != VAProcFilterSkinToneEnhancement &&
330 filter->type != VAProcFilterColorBalance) {
331 fprintf(stderr, "Do not support multiply filters outside vebox pipeline \n");
335 gen75_vpp_vebox(ctx, proc_ctx);
341 if(vpp_stage2 == 1) {
342 memset(&pipeline_param2, 0, sizeof(pipeline_param2));
343 pipeline_param2.surface = out_surface_id2;
344 pipeline_param2.surface_region = &dst_rect;
345 pipeline_param2.output_region = &dst_rect;
346 pipeline_param2.filter_flags = 0;
347 pipeline_param2.num_filters = 0;
349 proc_ctx->pipeline_param = &pipeline_param2;
350 proc_ctx->surface_pipeline_input_object = proc_ctx->surface_render_output_object;
351 proc_ctx->surface_render_output_object = obj_dst_surf;
354 gen75_vpp_vebox(ctx, proc_ctx);
357 if (num_tmp_surfaces)
358 i965_DestroySurfaces(ctx,
362 return VA_STATUS_SUCCESS;
365 if (num_tmp_surfaces)
366 i965_DestroySurfaces(ctx,
374 gen75_proc_context_destroy(void *hw_context)
376 struct intel_video_process_context *proc_ctx =
377 (struct intel_video_process_context *)hw_context;
378 VADriverContextP ctx = (VADriverContextP)(proc_ctx->driver_context);
380 if(proc_ctx->vpp_fmt_cvt_ctx){
381 proc_ctx->vpp_fmt_cvt_ctx->destroy(proc_ctx->vpp_fmt_cvt_ctx);
382 proc_ctx->vpp_fmt_cvt_ctx = NULL;
385 if(proc_ctx->vpp_vebox_ctx){
386 gen75_vebox_context_destroy(ctx,proc_ctx->vpp_vebox_ctx);
387 proc_ctx->vpp_vebox_ctx = NULL;
394 gen75_proc_context_init(VADriverContextP ctx,
395 struct object_config *obj_config)
397 struct intel_video_process_context *proc_context
398 = calloc(1, sizeof(struct intel_video_process_context));
400 assert(proc_context);
401 proc_context->base.destroy = gen75_proc_context_destroy;
402 proc_context->base.run = gen75_proc_picture;
404 proc_context->vpp_vebox_ctx = NULL;
405 proc_context->vpp_fmt_cvt_ctx = NULL;
407 proc_context->driver_context = ctx;
409 return (struct hw_context *)proc_context;