OSDN Git Service

Unify the coding style in the driver
[android-x86/hardware-intel-common-vaapi.git] / src / gen75_picture_process.c
1 /*
2  * Copyright © 2011 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *   Li Xiaowei <xiaowei.a.li@intel.com>
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <assert.h>
31 #include <string.h>
32
33 #include "intel_batchbuffer.h"
34 #include "intel_driver.h"
35 #include "i965_defines.h"
36 #include "i965_structs.h"
37
38 #include "i965_drv_video.h"
39 #include "i965_post_processing.h"
40 #include "gen75_picture_process.h"
41 #include "gen8_post_processing.h"
42 #include "intel_gen_vppapi.h"
43
44 extern struct hw_context *
45 i965_proc_context_init(VADriverContextP ctx,
46                        struct object_config *obj_config);
47
48 static VAStatus
49 gen75_vpp_fmt_cvt(VADriverContextP ctx,
50                   VAProfile profile,
51                   union codec_state *codec_state,
52                   struct hw_context *hw_context)
53 {
54     VAStatus va_status = VA_STATUS_SUCCESS;
55     struct intel_video_process_context *proc_ctx =
56         (struct intel_video_process_context *)hw_context;
57
58     va_status = i965_proc_picture(ctx, profile, codec_state,
59                                   proc_ctx->vpp_fmt_cvt_ctx);
60
61     return va_status;
62 }
63
64 static VAStatus
65 gen75_vpp_vebox(VADriverContextP ctx,
66                 struct intel_video_process_context* proc_ctx)
67 {
68     VAStatus va_status = VA_STATUS_SUCCESS;
69     VAProcPipelineParameterBuffer* pipeline_param = proc_ctx->pipeline_param;
70     struct i965_driver_data *i965 = i965_driver_data(ctx);
71
72     /* vpp features based on VEBox fixed function */
73     if (proc_ctx->vpp_vebox_ctx == NULL) {
74         proc_ctx->vpp_vebox_ctx = gen75_vebox_context_init(ctx);
75     }
76
77     proc_ctx->vpp_vebox_ctx->pipeline_param  = pipeline_param;
78     proc_ctx->vpp_vebox_ctx->surface_input_object = proc_ctx->surface_pipeline_input_object;
79     proc_ctx->vpp_vebox_ctx->surface_output_object  = proc_ctx->surface_render_output_object;
80
81     if (IS_HASWELL(i965->intel.device_info))
82         va_status = gen75_vebox_process_picture(ctx, proc_ctx->vpp_vebox_ctx);
83     else if (IS_GEN8(i965->intel.device_info))
84         va_status = gen8_vebox_process_picture(ctx, proc_ctx->vpp_vebox_ctx);
85     else if (IS_GEN9(i965->intel.device_info))
86         va_status = gen9_vebox_process_picture(ctx, proc_ctx->vpp_vebox_ctx);
87
88     return va_status;
89 }
90
91 static int intel_gpe_support_10bit_scaling(struct intel_video_process_context *proc_ctx)
92 {
93     struct i965_proc_context *gpe_proc_ctx;
94
95     if (!proc_ctx || !proc_ctx->vpp_fmt_cvt_ctx)
96         return 0;
97
98     gpe_proc_ctx = (struct i965_proc_context *)proc_ctx->vpp_fmt_cvt_ctx;
99
100     if (gpe_proc_ctx->pp_context.scaling_context_initialized)
101         return 1;
102     else
103         return 0;
104 }
105
106 static void
107 rgb_to_yuv(unsigned int argb,
108            unsigned char *y,
109            unsigned char *u,
110            unsigned char *v,
111            unsigned char *a)
112 {
113     int r = ((argb >> 16) & 0xff);
114     int g = ((argb >> 8) & 0xff);
115     int b = ((argb >> 0) & 0xff);
116
117     *y = (257 * r + 504 * g + 98 * b) / 1000 + 16;
118     *v = (439 * r - 368 * g - 71 * b) / 1000 + 128;
119     *u = (-148 * r - 291 * g + 439 * b) / 1000 + 128;
120     *a = ((argb >> 24) & 0xff);
121 }
122
123 static void
124 gen8plus_vpp_clear_surface(VADriverContextP ctx,
125                            struct i965_post_processing_context *pp_context,
126                            struct object_surface *obj_surface,
127                            unsigned int color)
128 {
129     struct intel_batchbuffer *batch = pp_context->batch;
130     unsigned int blt_cmd, br13;
131     unsigned int tiling = 0, swizzle = 0;
132     int pitch;
133     unsigned char y, u, v, a = 0;
134     int region_width, region_height;
135
136     /* Currently only support NV12 surface */
137     if (!obj_surface || obj_surface->fourcc != VA_FOURCC_NV12)
138         return;
139
140     rgb_to_yuv(color, &y, &u, &v, &a);
141
142     if (a == 0)
143         return;
144
145     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
146     blt_cmd = GEN8_XY_COLOR_BLT_CMD;
147     pitch = obj_surface->width;
148
149     if (tiling != I915_TILING_NONE) {
150         assert(tiling == I915_TILING_Y);
151         // blt_cmd |= XY_COLOR_BLT_DST_TILED;
152         // pitch >>= 2;
153     }
154
155     br13 = 0xf0 << 16;
156     br13 |= BR13_8;
157     br13 |= pitch;
158
159     intel_batchbuffer_start_atomic_blt(batch, 56);
160     BEGIN_BLT_BATCH(batch, 14);
161
162     region_width = obj_surface->width;
163     region_height = obj_surface->height;
164
165     OUT_BATCH(batch, blt_cmd);
166     OUT_BATCH(batch, br13);
167     OUT_BATCH(batch,
168               0 << 16 |
169               0);
170     OUT_BATCH(batch,
171               region_height << 16 |
172               region_width);
173     OUT_RELOC64(batch, obj_surface->bo,
174                 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
175                 0);
176     OUT_BATCH(batch, y);
177
178     br13 = 0xf0 << 16;
179     br13 |= BR13_565;
180     br13 |= pitch;
181
182     region_width = obj_surface->width / 2;
183     region_height = obj_surface->height / 2;
184
185     if (tiling == I915_TILING_Y) {
186         region_height = ALIGN(obj_surface->height / 2, 32);
187     }
188
189     OUT_BATCH(batch, blt_cmd);
190     OUT_BATCH(batch, br13);
191     OUT_BATCH(batch,
192               0 << 16 |
193               0);
194     OUT_BATCH(batch,
195               region_height << 16 |
196               region_width);
197     OUT_RELOC64(batch, obj_surface->bo,
198                 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
199                 obj_surface->width * obj_surface->y_cb_offset);
200     OUT_BATCH(batch, v << 8 | u);
201
202     ADVANCE_BATCH(batch);
203     intel_batchbuffer_end_atomic(batch);
204 }
205
206 VAStatus
207 gen75_proc_picture(VADriverContextP ctx,
208                    VAProfile profile,
209                    union codec_state *codec_state,
210                    struct hw_context *hw_context)
211 {
212     struct i965_driver_data *i965 = i965_driver_data(ctx);
213     struct proc_state* proc_st = &(codec_state->proc);
214     struct intel_video_process_context *proc_ctx =
215         (struct intel_video_process_context *)hw_context;
216     VAProcPipelineParameterBuffer *pipeline_param =
217         (VAProcPipelineParameterBuffer *)proc_st->pipeline_param->buffer;
218     struct object_surface *obj_dst_surf = NULL;
219     struct object_surface *obj_src_surf = NULL;
220
221     VAProcPipelineParameterBuffer pipeline_param2;
222     struct object_surface *stage1_dst_surf = NULL;
223     struct object_surface *stage2_dst_surf = NULL;
224     VARectangle src_rect, dst_rect;
225     VASurfaceID tmp_surfaces[2];
226     VASurfaceID out_surface_id1 = VA_INVALID_ID, out_surface_id2 = VA_INVALID_ID;
227     int num_tmp_surfaces = 0;
228
229     VAStatus status;
230
231     proc_ctx->pipeline_param = pipeline_param;
232
233     if (proc_st->current_render_target == VA_INVALID_SURFACE ||
234         pipeline_param->surface == VA_INVALID_SURFACE) {
235         status = VA_STATUS_ERROR_INVALID_SURFACE;
236         goto error;
237     }
238
239     obj_dst_surf = SURFACE(proc_st->current_render_target);
240
241     if (!obj_dst_surf) {
242         status = VA_STATUS_ERROR_INVALID_SURFACE;
243         goto error;
244     }
245
246     obj_src_surf = SURFACE(proc_ctx->pipeline_param->surface);
247
248     if (!obj_src_surf) {
249         status = VA_STATUS_ERROR_INVALID_SURFACE;
250         goto error;
251     }
252
253     if (!obj_src_surf->bo) {
254         status = VA_STATUS_ERROR_INVALID_VALUE; /* The input surface is created without valid content */
255         goto error;
256     }
257
258     if (pipeline_param->num_filters && !pipeline_param->filters) {
259         status = VA_STATUS_ERROR_INVALID_PARAMETER;
260         goto error;
261     }
262
263     if (pipeline_param->num_filters == 0 || pipeline_param->filters == NULL) {
264         /* explicitly initialize the VPP based on Render ring */
265         if (proc_ctx->vpp_fmt_cvt_ctx == NULL)
266             proc_ctx->vpp_fmt_cvt_ctx = i965_proc_context_init(ctx, NULL);
267     }
268
269     if (!obj_dst_surf->bo) {
270         unsigned int is_tiled = 1;
271         unsigned int fourcc = VA_FOURCC_NV12;
272         int sampling = SUBSAMPLE_YUV420;
273
274         if (obj_dst_surf->expected_format == VA_RT_FORMAT_YUV420_10BPP)
275             fourcc = VA_FOURCC_P010;
276
277         i965_check_alloc_surface_bo(ctx, obj_dst_surf, is_tiled, fourcc, sampling);
278     }
279
280     if (pipeline_param->surface_region) {
281         src_rect.x = pipeline_param->surface_region->x;
282         src_rect.y = pipeline_param->surface_region->y;
283         src_rect.width = pipeline_param->surface_region->width;
284         src_rect.height = pipeline_param->surface_region->height;
285     } else {
286         src_rect.x = 0;
287         src_rect.y = 0;
288         src_rect.width = obj_src_surf->orig_width;
289         src_rect.height = obj_src_surf->orig_height;
290     }
291
292     if (pipeline_param->output_region) {
293         dst_rect.x = pipeline_param->output_region->x;
294         dst_rect.y = pipeline_param->output_region->y;
295         dst_rect.width = pipeline_param->output_region->width;
296         dst_rect.height = pipeline_param->output_region->height;
297     } else {
298         dst_rect.x = 0;
299         dst_rect.y = 0;
300         dst_rect.width = obj_dst_surf->orig_width;
301         dst_rect.height = obj_dst_surf->orig_height;
302     }
303
304     if (pipeline_param->num_filters == 0 || pipeline_param->filters == NULL) {
305         /* The Bit 2 is used to indicate that it is 10bit or 8bit.
306          * The Bit 0/1 is used to indicate the 420/422/444 format
307          */
308 #define SRC_10BIT_420    (5 << 0)
309 #define SRC_10BIT_422    (6 << 0)
310 #define SRC_10BIT_444    (7 << 0)
311 #define SRC_8BIT_420     (1 << 0)
312
313         /* The Bit 6 is used to indicate that it is 10bit or 8bit.
314          * The Bit 5/4 is used to indicate the 420/422/444 format
315          */
316 #define DST_10BIT_420    (5 << 4)
317 #define DST_10BIT_422    (6 << 4)
318 #define DST_10BIT_444    (7 << 4)
319 #define DST_8BIT_420     (1 << 4)
320
321         /* This is mainly for YUY2/RGBA. It is reserved for further */
322 #define SRC_YUV_PACKED   (1 << 3)
323 #define DST_YUV_PACKED   (1 << 7)
324
325 #define MASK_CSC         (0xFF)
326 #define SCALE_10BIT_420  (SRC_10BIT_420 | DST_10BIT_420)
327 #define SCALE_8BIT_420  (SRC_8BIT_420 | DST_8BIT_420)
328
329         unsigned int scale_flag;
330
331         scale_flag = 0;
332         if (obj_src_surf->fourcc == VA_FOURCC_P010 ||
333             obj_src_surf->fourcc == VA_FOURCC_I010)
334             scale_flag |= SRC_10BIT_420;
335
336         if (obj_dst_surf->fourcc == VA_FOURCC_P010 ||
337             obj_dst_surf->fourcc == VA_FOURCC_I010)
338             scale_flag |= DST_10BIT_420;
339
340         if (obj_src_surf->fourcc == VA_FOURCC_NV12 ||
341             obj_src_surf->fourcc == VA_FOURCC_I420)
342             scale_flag |= SRC_8BIT_420;
343
344         if (obj_dst_surf->fourcc == VA_FOURCC_NV12 ||
345             obj_dst_surf->fourcc == VA_FOURCC_I420)
346             scale_flag |= DST_8BIT_420;
347
348         /* If P010 is converted without resolution change,
349          * fall back to VEBOX
350          */
351         if (i965->intel.has_vebox &&
352             (obj_src_surf->fourcc == VA_FOURCC_P010) &&
353             (obj_dst_surf->fourcc == VA_FOURCC_P010) &&
354             (src_rect.width == dst_rect.width) &&
355             (src_rect.height == dst_rect.height))
356             scale_flag = 0;
357
358         if (((scale_flag & MASK_CSC) == SCALE_10BIT_420) &&
359             intel_gpe_support_10bit_scaling(proc_ctx)) {
360             struct i965_proc_context *gpe_proc_ctx;
361             struct i965_surface src_surface, dst_surface;
362             unsigned int tmp_width, tmp_x;
363
364
365             src_surface.base = (struct object_base *)obj_src_surf;
366             src_surface.type = I965_SURFACE_TYPE_SURFACE;
367             dst_surface.base = (struct object_base *)obj_dst_surf;
368             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
369             gpe_proc_ctx = (struct i965_proc_context *)proc_ctx->vpp_fmt_cvt_ctx;
370
371             tmp_x = ALIGN_FLOOR(dst_rect.x, 2);
372             tmp_width = dst_rect.x + dst_rect.width;
373             tmp_width = tmp_width - tmp_x;
374             dst_rect.x = tmp_x;
375             dst_rect.width = tmp_width;
376
377             return gen9_p010_scaling_post_processing(ctx, &gpe_proc_ctx->pp_context,
378                                                      &src_surface, &src_rect,
379                                                      &dst_surface, &dst_rect);
380         }
381         if (((scale_flag & MASK_CSC) == SCALE_8BIT_420) &&
382             intel_vpp_support_yuv420p8_scaling(proc_ctx)) {
383             struct i965_proc_context *gpe_proc_ctx;
384             struct i965_surface src_surface, dst_surface;
385             unsigned int tmp_width, tmp_x;
386
387
388             src_surface.base = (struct object_base *)obj_src_surf;
389             src_surface.type = I965_SURFACE_TYPE_SURFACE;
390             dst_surface.base = (struct object_base *)obj_dst_surf;
391             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
392             gpe_proc_ctx = (struct i965_proc_context *)proc_ctx->vpp_fmt_cvt_ctx;
393
394             tmp_x = ALIGN_FLOOR(dst_rect.x, 4);
395             tmp_width = dst_rect.x + dst_rect.width;
396             tmp_width = tmp_width - tmp_x;
397             dst_rect.x = tmp_x;
398             dst_rect.width = tmp_width;
399
400             if (obj_dst_surf->fourcc == VA_FOURCC_NV12 &&
401                 pipeline_param->output_background_color)
402                 gen8plus_vpp_clear_surface(ctx, &gpe_proc_ctx->pp_context,
403                                            obj_dst_surf,
404                                            pipeline_param->output_background_color);
405
406             return intel_yuv420p8_scaling_post_processing(ctx, &gpe_proc_ctx->pp_context,
407                                                           &src_surface, &src_rect,
408                                                           &dst_surface, &dst_rect);
409         }
410     }
411
412     proc_ctx->surface_render_output_object = obj_dst_surf;
413     proc_ctx->surface_pipeline_input_object = obj_src_surf;
414     assert(pipeline_param->num_filters <= 4);
415
416     int vpp_stage1 = 0, vpp_stage2 = 1, vpp_stage3 = 0;
417
418
419     if (obj_src_surf->fourcc == VA_FOURCC_P010) {
420         vpp_stage1 = 1;
421         vpp_stage2 = 0;
422         vpp_stage3 = 0;
423         if (pipeline_param->num_filters == 0 || pipeline_param->filters == NULL) {
424             if (src_rect.x != dst_rect.x ||
425                 src_rect.y != dst_rect.y ||
426                 src_rect.width != dst_rect.width ||
427                 src_rect.height != dst_rect.height)
428                 vpp_stage2 = 1;
429
430             if (obj_dst_surf->fourcc != VA_FOURCC_NV12 &&
431                 obj_dst_surf->fourcc != VA_FOURCC_P010)
432                 vpp_stage2 = 1;
433         } else
434             vpp_stage2 = 1;
435
436         if (vpp_stage2 == 1) {
437             if (obj_dst_surf->fourcc == VA_FOURCC_P010)
438                 vpp_stage3 = 1;
439         }
440     } else if (obj_dst_surf->fourcc == VA_FOURCC_P010) {
441         vpp_stage2 = 1;
442         vpp_stage3 = 1;
443
444         if ((obj_src_surf->fourcc == VA_FOURCC_NV12) &&
445             (pipeline_param->num_filters == 0 || pipeline_param->filters == NULL)) {
446             if ((src_rect.x == dst_rect.x) &&
447                 (src_rect.y == dst_rect.y) &&
448                 (src_rect.width == dst_rect.width) &&
449                 (src_rect.height == dst_rect.height))
450                 vpp_stage2 = 0;
451         }
452     }
453
454     if (vpp_stage1 == 1) {
455         memset((void *)&pipeline_param2, 0, sizeof(pipeline_param2));
456         pipeline_param2.surface = pipeline_param->surface;
457         pipeline_param2.surface_region = &src_rect;
458         pipeline_param2.output_region = &src_rect;
459         pipeline_param2.filter_flags = 0;
460         pipeline_param2.num_filters  = 0;
461
462         proc_ctx->pipeline_param = &pipeline_param2;
463
464         if (vpp_stage2 == 1) {
465             status = i965_CreateSurfaces(ctx,
466                                          obj_src_surf->orig_width,
467                                          obj_src_surf->orig_height,
468                                          VA_RT_FORMAT_YUV420,
469                                          1,
470                                          &out_surface_id1);
471             assert(status == VA_STATUS_SUCCESS);
472             tmp_surfaces[num_tmp_surfaces++] = out_surface_id1;
473             stage1_dst_surf = SURFACE(out_surface_id1);
474             assert(stage1_dst_surf);
475             i965_check_alloc_surface_bo(ctx, stage1_dst_surf, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
476
477             proc_ctx->surface_render_output_object = stage1_dst_surf;
478         }
479
480         gen75_vpp_vebox(ctx, proc_ctx);
481     }
482
483     if ((vpp_stage3 == 1) && (vpp_stage2 == 1)) {
484         status = i965_CreateSurfaces(ctx,
485                                      obj_dst_surf->orig_width,
486                                      obj_dst_surf->orig_height,
487                                      VA_RT_FORMAT_YUV420,
488                                      1,
489                                      &out_surface_id2);
490         assert(status == VA_STATUS_SUCCESS);
491         tmp_surfaces[num_tmp_surfaces++] = out_surface_id2;
492         stage2_dst_surf = SURFACE(out_surface_id2);
493         assert(stage2_dst_surf);
494         i965_check_alloc_surface_bo(ctx, stage2_dst_surf, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
495     }
496
497     VABufferID *filter_id = (VABufferID*) pipeline_param->filters;
498
499     if (vpp_stage2 == 1) {
500         if (stage1_dst_surf != NULL) {
501             proc_ctx->surface_pipeline_input_object = stage1_dst_surf;
502             proc_ctx->surface_render_output_object = obj_dst_surf;
503
504             pipeline_param->surface = out_surface_id1;
505         }
506
507         if (stage2_dst_surf != NULL) {
508             proc_ctx->surface_render_output_object = stage2_dst_surf;
509
510             proc_st->current_render_target = out_surface_id2;
511         }
512
513         proc_ctx->pipeline_param = pipeline_param;
514
515         if (pipeline_param->num_filters == 0 || pipeline_param->filters == NULL) {
516             /* implicity surface format coversion and scaling */
517
518             status = gen75_vpp_fmt_cvt(ctx, profile, codec_state, hw_context);
519             if (status != VA_STATUS_SUCCESS)
520                 goto error;
521         } else if (pipeline_param->num_filters == 1) {
522             struct object_buffer * obj_buf = BUFFER((*filter_id) + 0);
523
524             assert(obj_buf && obj_buf->buffer_store && obj_buf->buffer_store->buffer);
525
526             if (!obj_buf ||
527                 !obj_buf->buffer_store ||
528                 !obj_buf->buffer_store->buffer) {
529                 status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
530                 goto error;
531             }
532
533             VAProcFilterParameterBuffer* filter =
534                 (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
535
536             if (filter->type == VAProcFilterNoiseReduction         ||
537                 filter->type == VAProcFilterDeinterlacing          ||
538                 filter->type == VAProcFilterSkinToneEnhancement    ||
539                 filter->type == VAProcFilterSharpening             ||
540                 filter->type == VAProcFilterColorBalance) {
541                 gen75_vpp_vebox(ctx, proc_ctx);
542             }
543         } else if (pipeline_param->num_filters >= 2) {
544             unsigned int i = 0;
545             for (i = 0; i < pipeline_param->num_filters; i++) {
546                 struct object_buffer * obj_buf = BUFFER(pipeline_param->filters[i]);
547
548                 if (!obj_buf ||
549                     !obj_buf->buffer_store ||
550                     !obj_buf->buffer_store->buffer) {
551                     status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
552                     goto error;
553                 }
554
555                 VAProcFilterParameterBuffer* filter =
556                     (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
557
558                 if (filter->type != VAProcFilterNoiseReduction       &&
559                     filter->type != VAProcFilterDeinterlacing        &&
560                     filter->type != VAProcFilterSkinToneEnhancement  &&
561                     filter->type != VAProcFilterColorBalance) {
562                     fprintf(stderr, "Do not support multiply filters outside vebox pipeline \n");
563                     assert(0);
564                 }
565             }
566             gen75_vpp_vebox(ctx, proc_ctx);
567         }
568     }
569
570     if (vpp_stage3 == 1) {
571         if (vpp_stage2 == 1) {
572             memset(&pipeline_param2, 0, sizeof(pipeline_param2));
573             pipeline_param2.surface = out_surface_id2;
574             pipeline_param2.surface_region = &dst_rect;
575             pipeline_param2.output_region = &dst_rect;
576             pipeline_param2.filter_flags = 0;
577             pipeline_param2.num_filters  = 0;
578
579             proc_ctx->pipeline_param = &pipeline_param2;
580             proc_ctx->surface_pipeline_input_object = proc_ctx->surface_render_output_object;
581             proc_ctx->surface_render_output_object = obj_dst_surf;
582         }
583
584         gen75_vpp_vebox(ctx, proc_ctx);
585     }
586
587     if (num_tmp_surfaces)
588         i965_DestroySurfaces(ctx,
589                              tmp_surfaces,
590                              num_tmp_surfaces);
591
592     return VA_STATUS_SUCCESS;
593
594 error:
595     if (num_tmp_surfaces)
596         i965_DestroySurfaces(ctx,
597                              tmp_surfaces,
598                              num_tmp_surfaces);
599
600     return status;
601 }
602
603 static void
604 gen75_proc_context_destroy(void *hw_context)
605 {
606     struct intel_video_process_context *proc_ctx =
607         (struct intel_video_process_context *)hw_context;
608     VADriverContextP ctx = (VADriverContextP)(proc_ctx->driver_context);
609
610     if (proc_ctx->vpp_fmt_cvt_ctx) {
611         proc_ctx->vpp_fmt_cvt_ctx->destroy(proc_ctx->vpp_fmt_cvt_ctx);
612         proc_ctx->vpp_fmt_cvt_ctx = NULL;
613     }
614
615     if (proc_ctx->vpp_vebox_ctx) {
616         gen75_vebox_context_destroy(ctx, proc_ctx->vpp_vebox_ctx);
617         proc_ctx->vpp_vebox_ctx = NULL;
618     }
619
620     free(proc_ctx);
621 }
622
623 struct hw_context *
624 gen75_proc_context_init(VADriverContextP ctx,
625                         struct object_config *obj_config)
626 {
627     struct intel_video_process_context *proc_context
628         = calloc(1, sizeof(struct intel_video_process_context));
629
630     assert(proc_context);
631     proc_context->base.destroy = gen75_proc_context_destroy;
632     proc_context->base.run     = gen75_proc_picture;
633
634     proc_context->vpp_vebox_ctx    = NULL;
635     proc_context->vpp_fmt_cvt_ctx  = NULL;
636
637     proc_context->driver_context = ctx;
638
639     return (struct hw_context *)proc_context;
640 }
641