VEBOX/bdw: set downsample method
[platform/upstream/libva-intel-driver.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
32 #include "intel_batchbuffer.h"
33 #include "intel_driver.h"
34 #include "i965_defines.h"
35 #include "i965_structs.h"
36
37 #include "i965_drv_video.h"
38 #include "i965_post_processing.h"
39 #include "gen75_picture_process.h"
40
41 extern void
42 i965_proc_picture(VADriverContextP ctx, 
43                   VAProfile profile, 
44                   union codec_state *codec_state,
45                   struct hw_context *hw_context);
46
47 extern struct hw_context *
48 i965_proc_context_init(VADriverContextP ctx,
49                        struct object_config *obj_config);
50
51 static VAStatus 
52 gen75_vpp_fmt_cvt(VADriverContextP ctx, 
53                   VAProfile profile, 
54                   union codec_state *codec_state,
55                   struct hw_context *hw_context)
56 {
57     VAStatus va_status = VA_STATUS_SUCCESS;
58     struct intel_video_process_context *proc_ctx = 
59              (struct intel_video_process_context *)hw_context;
60   
61     /* implicity surface format coversion and scaling */
62     if(proc_ctx->vpp_fmt_cvt_ctx == NULL){
63          proc_ctx->vpp_fmt_cvt_ctx = i965_proc_context_init(ctx, NULL);
64     }
65
66     i965_proc_picture(ctx, profile, codec_state, 
67                       proc_ctx->vpp_fmt_cvt_ctx);
68
69     return va_status;
70 }
71
72 static VAStatus 
73 gen75_vpp_vebox(VADriverContextP ctx, 
74                 struct intel_video_process_context* proc_ctx)
75 {
76      VAStatus va_status = VA_STATUS_SUCCESS;
77      VAProcPipelineParameterBuffer* pipeline_param = proc_ctx->pipeline_param; 
78      struct i965_driver_data *i965 = i965_driver_data(ctx); 
79  
80      /* vpp features based on VEBox fixed function */
81      if(proc_ctx->vpp_vebox_ctx == NULL) {
82          proc_ctx->vpp_vebox_ctx = gen75_vebox_context_init(ctx);
83      }
84
85      proc_ctx->vpp_vebox_ctx->pipeline_param  = pipeline_param;
86      proc_ctx->vpp_vebox_ctx->surface_input_object = proc_ctx->surface_pipeline_input_object;
87      proc_ctx->vpp_vebox_ctx->surface_output_object  = proc_ctx->surface_render_output_object;
88
89      if (IS_HASWELL(i965->intel.device_id))
90          va_status = gen75_vebox_process_picture(ctx, proc_ctx->vpp_vebox_ctx);
91      else if (IS_GEN8(i965->intel.device_id))
92          va_status = gen8_vebox_process_picture(ctx, proc_ctx->vpp_vebox_ctx);
93  
94      return va_status;
95
96
97 static VAStatus 
98 gen75_vpp_gpe(VADriverContextP ctx, 
99               struct intel_video_process_context* proc_ctx)
100 {
101      VAStatus va_status = VA_STATUS_SUCCESS;
102
103      if(proc_ctx->vpp_gpe_ctx == NULL){
104          proc_ctx->vpp_gpe_ctx = gen75_gpe_context_init(ctx);
105      }
106    
107      proc_ctx->vpp_gpe_ctx->pipeline_param = proc_ctx->pipeline_param;
108      proc_ctx->vpp_gpe_ctx->surface_pipeline_input_object = proc_ctx->surface_pipeline_input_object;
109      proc_ctx->vpp_gpe_ctx->surface_output_object = proc_ctx->surface_render_output_object;
110
111      va_status = gen75_gpe_process_picture(ctx, proc_ctx->vpp_gpe_ctx);
112  
113      return va_status;     
114 }
115
116 VAStatus 
117 gen75_proc_picture(VADriverContextP ctx,
118                    VAProfile profile,
119                    union codec_state *codec_state,
120                    struct hw_context *hw_context)
121 {
122     struct i965_driver_data *i965 = i965_driver_data(ctx);
123     struct proc_state* proc_st = &(codec_state->proc);
124     struct intel_video_process_context *proc_ctx = 
125              (struct intel_video_process_context *)hw_context;
126     VAProcPipelineParameterBuffer *pipeline_param = 
127              (VAProcPipelineParameterBuffer *)proc_st->pipeline_param->buffer;
128     struct object_surface *obj_dst_surf = NULL;
129     struct object_surface *obj_src_surf = NULL;
130     VAStatus status;
131
132     proc_ctx->pipeline_param = pipeline_param;
133
134     if (proc_st->current_render_target == VA_INVALID_SURFACE ||
135         pipeline_param->surface == VA_INVALID_SURFACE) {
136         status = VA_STATUS_ERROR_INVALID_SURFACE;
137         goto error;
138     }
139
140     obj_dst_surf = SURFACE(proc_st->current_render_target);
141
142     if (!obj_dst_surf) {
143         status = VA_STATUS_ERROR_INVALID_SURFACE;
144         goto error;
145     }
146
147     obj_src_surf = SURFACE(proc_ctx->pipeline_param->surface);
148
149     if (!obj_src_surf) {
150         status = VA_STATUS_ERROR_INVALID_SURFACE;
151         goto error;
152     }
153
154     if (!obj_src_surf->bo) {
155         status = VA_STATUS_ERROR_INVALID_VALUE; /* The input surface is created without valid content */
156         goto error;
157     }
158
159     if (pipeline_param->num_filters && !pipeline_param->filters) {
160         status = VA_STATUS_ERROR_INVALID_PARAMETER;
161         goto error;
162     }
163
164     if (!obj_dst_surf->bo) {
165         unsigned int is_tiled = 0;
166         unsigned int fourcc = VA_FOURCC('N','V','1','2');
167         int sampling = SUBSAMPLE_YUV420;
168         i965_check_alloc_surface_bo(ctx, obj_dst_surf, is_tiled, fourcc, sampling);
169     }  
170
171     proc_ctx->surface_render_output_object = obj_dst_surf;
172     proc_ctx->surface_pipeline_input_object = obj_src_surf;
173     assert(pipeline_param->num_filters <= 4);
174
175     VABufferID *filter_id = (VABufferID*) pipeline_param->filters;
176  
177     if(pipeline_param->num_filters == 0 || pipeline_param->filters == NULL ){
178         /* implicity surface format coversion and scaling */
179         gen75_vpp_fmt_cvt(ctx, profile, codec_state, hw_context);
180     }else if(pipeline_param->num_filters == 1) {
181        struct object_buffer * obj_buf = BUFFER((*filter_id) + 0);
182
183        assert(obj_buf && obj_buf->buffer_store && obj_buf->buffer_store->buffer);
184        
185        if (!obj_buf ||
186            !obj_buf->buffer_store ||
187            !obj_buf->buffer_store->buffer) {
188            status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
189            goto error;
190        }
191
192        VAProcFilterParameterBuffer* filter =
193            (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
194
195        if (filter->type == VAProcFilterNoiseReduction   ||
196            filter->type == VAProcFilterDeinterlacing    ||
197            filter->type == VAProcFilterColorBalance){
198            gen75_vpp_vebox(ctx, proc_ctx);
199        }else if(filter->type == VAProcFilterSharpening){
200            if (obj_src_surf->fourcc != VA_FOURCC('N', 'V', '1', '2') ||
201                obj_dst_surf->fourcc != VA_FOURCC('N', 'V', '1', '2')) {
202                status = VA_STATUS_ERROR_UNIMPLEMENTED;
203                goto error;
204            }
205
206            gen75_vpp_gpe(ctx, proc_ctx);
207        } 
208     }else if (pipeline_param->num_filters >= 2) {
209          unsigned int i = 0;
210          for (i = 0; i < pipeline_param->num_filters; i++){
211              struct object_buffer * obj_buf = BUFFER(pipeline_param->filters[i]);
212
213              if (!obj_buf ||
214                  !obj_buf->buffer_store ||
215                  !obj_buf->buffer_store->buffer) {
216                  status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
217                  goto error;
218              }
219
220              VAProcFilterParameterBuffer* filter =
221                  (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
222
223              if (filter->type != VAProcFilterNoiseReduction &&
224                  filter->type != VAProcFilterDeinterlacing  &&
225                  filter->type != VAProcFilterColorBalance) {
226                  printf("Do not support multiply filters outside vebox pipeline \n");
227                  assert(0);
228              }
229          }
230          gen75_vpp_vebox(ctx, proc_ctx);
231     }     
232
233     return VA_STATUS_SUCCESS;
234
235 error:
236     return status;
237 }
238
239 static void 
240 gen75_proc_context_destroy(void *hw_context)
241 {
242     struct intel_video_process_context *proc_ctx =
243                       (struct intel_video_process_context *)hw_context;
244     VADriverContextP ctx = (VADriverContextP)(proc_ctx->driver_context);
245
246     if(proc_ctx->vpp_fmt_cvt_ctx){
247         proc_ctx->vpp_fmt_cvt_ctx->destroy(proc_ctx->vpp_fmt_cvt_ctx);
248         proc_ctx->vpp_fmt_cvt_ctx = NULL;
249     }
250
251     if(proc_ctx->vpp_vebox_ctx){
252        gen75_vebox_context_destroy(ctx,proc_ctx->vpp_vebox_ctx);
253        proc_ctx->vpp_vebox_ctx = NULL;
254     }
255
256     if(proc_ctx->vpp_gpe_ctx){
257        gen75_gpe_context_destroy(ctx,proc_ctx->vpp_gpe_ctx);
258        proc_ctx->vpp_gpe_ctx = NULL;
259     }
260
261     free(proc_ctx);
262 }
263
264 struct hw_context * 
265 gen75_proc_context_init(VADriverContextP ctx, 
266                         struct object_config *obj_config)
267 {
268    struct intel_video_process_context *proc_context 
269            = calloc(1, sizeof(struct intel_video_process_context));
270
271     proc_context->base.destroy = gen75_proc_context_destroy;
272     proc_context->base.run     = gen75_proc_picture;
273
274     proc_context->vpp_vebox_ctx    = NULL;
275     proc_context->vpp_gpe_ctx      = NULL;
276     proc_context->vpp_fmt_cvt_ctx  = NULL;
277  
278     proc_context->driver_context = ctx;
279
280     return (struct hw_context *)proc_context;
281 }
282