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