VPP: Support multi filters for vebox pipeline
[profile/ivi/vaapi-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 static VAStatus 
48 gen75_vpp_fmt_cvt(VADriverContextP ctx, 
49                   VAProfile profile, 
50                   union codec_state *codec_state,
51                   struct hw_context *hw_context)
52 {
53     VAStatus va_status = VA_STATUS_SUCCESS;
54     struct intel_video_process_context *proc_ctx = 
55              (struct intel_video_process_context *)hw_context;
56   
57     /* implicity surface format coversion and scaling */
58     if(proc_ctx->vpp_fmt_cvt_ctx == NULL){
59          proc_ctx->vpp_fmt_cvt_ctx = i965_proc_context_init(ctx, NULL);
60     }
61
62     i965_proc_picture(ctx, profile, codec_state, 
63                       (struct hw_context *) proc_ctx->vpp_fmt_cvt_ctx);
64
65     return va_status;
66 }
67
68 static VAStatus 
69 gen75_vpp_vebox(VADriverContextP ctx, 
70                 struct intel_video_process_context* proc_ctx)
71 {
72      VAStatus va_status = VA_STATUS_SUCCESS;
73      VAProcPipelineParameterBuffer* pipeline_param = proc_ctx->pipeline_param; 
74  
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);
78      }
79
80      proc_ctx->vpp_vebox_ctx->pipeline_param  = pipeline_param;
81      proc_ctx->vpp_vebox_ctx->surface_input   = pipeline_param->surface;
82      proc_ctx->vpp_vebox_ctx->surface_output  = proc_ctx->surface_render_output;
83
84      va_status = gen75_vebox_process_picture(ctx, proc_ctx->vpp_vebox_ctx);
85  
86      return va_status;
87
88
89 static VAStatus 
90 gen75_vpp_gpe(VADriverContextP ctx, 
91               struct intel_video_process_context* proc_ctx)
92 {
93      VAStatus va_status = VA_STATUS_SUCCESS;
94
95      if(proc_ctx->vpp_gpe_ctx == NULL){
96          proc_ctx->vpp_gpe_ctx = gen75_gpe_context_init(ctx);
97      }
98    
99      proc_ctx->vpp_gpe_ctx->pipeline_param = proc_ctx->pipeline_param; 
100      proc_ctx->vpp_gpe_ctx->surface_output = proc_ctx->surface_render_output;
101
102      va_status = gen75_gpe_process_picture(ctx, proc_ctx->vpp_gpe_ctx);
103  
104      return va_status;     
105 }
106
107 void 
108 gen75_proc_picture(VADriverContextP ctx,
109                    VAProfile profile,
110                    union codec_state *codec_state,
111                    struct hw_context *hw_context)
112 {
113     struct i965_driver_data *i965 = i965_driver_data(ctx);
114     struct proc_state* proc_st = &(codec_state->proc);
115     struct intel_video_process_context *proc_ctx = 
116              (struct intel_video_process_context *)hw_context;
117     VAProcPipelineParameterBuffer *pipeline_param = 
118              (VAProcPipelineParameterBuffer *)proc_st->pipeline_param->buffer;
119
120     proc_ctx->pipeline_param = pipeline_param;
121     proc_ctx->surface_render_output = proc_st->current_render_target;
122
123     assert(proc_ctx->surface_render_output != VA_INVALID_SURFACE);
124
125     struct object_surface * obj_dst_surf = SURFACE(proc_ctx->surface_render_output);
126     if(!obj_dst_surf->bo){
127        unsigned int is_tiled = 0;
128        unsigned int fourcc = VA_FOURCC('N','V','1','2');
129        int sampling = SUBSAMPLE_YUV420;
130        i965_check_alloc_surface_bo(ctx, obj_dst_surf, is_tiled, fourcc, sampling);
131     }  
132
133     assert(pipeline_param->num_filters <= 4);
134
135     VABufferID *filter_id = (VABufferID*) pipeline_param->filters;
136  
137     if(pipeline_param->num_filters == 0 || pipeline_param->filters == NULL ){
138         /* implicity surface format coversion and scaling */
139         gen75_vpp_fmt_cvt(ctx, profile, codec_state, hw_context);
140     }else if(pipeline_param->num_filters == 1) {
141        struct object_buffer * obj_buf = BUFFER((*filter_id) + 0);
142        VAProcFilterParameterBuffer* filter =
143            (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
144
145        if(filter->type == VAProcFilterNone){ 
146            gen75_vpp_fmt_cvt(ctx, profile, codec_state, hw_context);
147        } else if(filter->type == VAProcFilterNoiseReduction   ||
148                  filter->type == VAProcFilterDeinterlacing    ||
149                  filter->type == VAProcFilterColorBalance){
150            gen75_vpp_vebox(ctx, proc_ctx);
151        }else if(filter->type == VAProcFilterSharpening){
152            struct object_surface *obj_src_surf = SURFACE(proc_ctx->pipeline_param->surface);
153            assert(obj_src_surf->fourcc == VA_FOURCC('N','V','1','2') && 
154                   obj_dst_surf->fourcc == VA_FOURCC('N','V','1','2'));   
155            gen75_vpp_gpe(ctx, proc_ctx);
156        } 
157     }else if (pipeline_param->num_filters >= 2) {
158          unsigned int i = 0;
159          for (i = 0; i < pipeline_param->num_filters; i++){
160             struct object_buffer * obj_buf = BUFFER(pipeline_param->filters[i]);
161             VAProcFilterParameterBuffer* filter =
162                (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
163
164             if (filter->type != VAProcFilterNoiseReduction &&
165                 filter->type != VAProcFilterDeinterlacing  &&
166                 filter->type != VAProcFilterColorBalance   && 
167                 filter->type != VAProcFilterNone ){ 
168                 printf("Do not support multiply filters outside vebox pipeline \n");
169                 assert(0);
170             }
171          }
172          gen75_vpp_vebox(ctx, proc_ctx);
173     }     
174 }
175
176 static void 
177 gen75_proc_context_destroy(void *hw_context)
178 {
179     struct intel_video_process_context *proc_ctx =
180                       (struct intel_video_process_context *)hw_context;
181     VADriverContextP ctx = (VADriverContextP)(proc_ctx->driver_context);
182
183     if(proc_ctx->vpp_fmt_cvt_ctx){
184         proc_ctx->vpp_fmt_cvt_ctx->base.destroy(proc_ctx->vpp_fmt_cvt_ctx);
185         proc_ctx->vpp_fmt_cvt_ctx = NULL;
186     }
187
188     if(proc_ctx->vpp_vebox_ctx){
189        gen75_vebox_context_destroy(ctx,proc_ctx->vpp_vebox_ctx);
190        proc_ctx->vpp_vebox_ctx = NULL;
191     }
192
193     if(proc_ctx->vpp_gpe_ctx){
194        gen75_gpe_context_destroy(ctx,proc_ctx->vpp_gpe_ctx);
195        proc_ctx->vpp_gpe_ctx = NULL;
196     }
197
198     free(proc_ctx);
199 }
200
201 struct hw_context * 
202 gen75_proc_context_init(VADriverContextP ctx, 
203                         struct object_config *obj_config)
204 {
205    struct intel_video_process_context *proc_context 
206            = calloc(1, sizeof(struct intel_video_process_context));
207
208     proc_context->base.destroy = gen75_proc_context_destroy;
209     proc_context->base.run     = gen75_proc_picture;
210
211     proc_context->vpp_vebox_ctx    = NULL;
212     proc_context->vpp_gpe_ctx      = NULL;
213     proc_context->vpp_fmt_cvt_ctx  = NULL;
214  
215     proc_context->driver_context = ctx;
216
217     return (struct hw_context *)proc_context;
218 }
219