1 /*
2  * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
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  *    Binglin Chen <binglin.chen@intel.com>
26  *
27  */
28 
29 #include "vsp_VPP.h"
30 #include "psb_buffer.h"
31 #include "psb_surface.h"
32 #include "vsp_cmdbuf.h"
33 #include "psb_drv_debug.h"
34 #include "vsp_compose.h"
35 
36 #include <strings.h>
37 
38 #define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
39 #define INIT_CONTEXT_VPP    context_VPP_p ctx = (context_VPP_p) obj_context->format_data;
40 #define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
41 #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
42 #define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
43 
44 #define SURFACE(id)    ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id ))
45 
46 #define KB 1024
47 #define MB (KB * KB)
48 #define VSP_CONTEXT_BUF_SIZE (60*KB)
49 #define VSP_INTERMEDIATE_BUF_SIZE (29*MB)
50 
51 #define MAX_VPP_PARAM (100)
52 #define MIN_VPP_PARAM (0)
53 #define STEP_VPP_PARAM (33)
54 #define MAX_VPP_AUTO_PARAM (1)
55 #define MIN_VPP_AUTO_PARAM (0)
56 #define STEP_VPP_AUTO_PARAM (1)
57 
58 #define VSP_FORWARD_REF_NUM 3
59 
60 #define VSP_COLOR_ENHANCE_FEATURES 2
61 
62 #define ALIGN_TO_128(value) ((value + 128 - 1) & ~(128 - 1))
63 #define ALIGN_TO_16(value) ((value + 16 - 1) & ~(16 - 1))
64 
65 #define QVGA_AREA (320 * 240)
66 #define VGA_AREA (640 * 480)
67 #define SD_AREA (720 * 576)
68 #define HD720P_AREA (1280 * 720)
69 #define HD1080P_AREA (1920 * 1088)
70 
71 #define MIN_SUPPORTED_HEIGHT 96
72 #define MAX_SUPPORTED_HEIGHT 1088
73 
74 /**
75  * The number of supported filter is 5:
76  * VAProcFilterDeblocking
77  * VAProcFilterNoiseReduction
78  * VAProcFilterSharpening
79  * VAProcFilterColorBalance
80  * VAProcFilterFrameRateConversion
81  */
82 #define VSP_SUPPORTED_FILTERS_NUM 5
83 
84 /* The size of supported color standard */
85 #define COLOR_STANDARDS_NUM 1
86 
87 enum resolution_set {
88 	NOT_SUPPORTED_RESOLUTION = -1,
89 	QCIF_TO_QVGA = 0,
90 	QVGA_TO_VGA,
91 	VGA_TO_SD,
92 	SD_TO_720P,
93 	HD720P_TO_1080P,
94 	RESOLUTION_SET_NUM
95 };
96 
97 struct vpp_chain_capability {
98 	int frc_enabled;
99 	int sharpen_enabled;
100 	int color_balance_enabled;
101 	int denoise_enabled;
102 	int deblock_enabled;
103 };
104 
105 enum filter_status {
106 	FILTER_DISABLED = 0,
107 	FILTER_ENABLED
108 };
109 
110 struct vpp_chain_capability vpp_chain_caps[RESOLUTION_SET_NUM] = {
111 	[HD720P_TO_1080P] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_DISABLED, FILTER_DISABLED},
112 	[SD_TO_720P] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_DISABLED, FILTER_DISABLED},
113 	[VGA_TO_SD] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_DISABLED, FILTER_DISABLED},
114 	[QVGA_TO_VGA] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED},
115 	[QCIF_TO_QVGA] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_ENABLED}
116 };
117 
118 struct filter_strength {
119 	struct VssProcDenoiseParameterBuffer denoise_deblock[RESOLUTION_SET_NUM];
120 	struct VssProcColorEnhancementParameterBuffer enhancer[RESOLUTION_SET_NUM];
121 	struct VssProcSharpenParameterBuffer sharpen[RESOLUTION_SET_NUM];
122 };
123 
124 enum filter_strength_type {
125 	INVALID_STRENGTH = -1,
126 	LOW_STRENGTH = 0,
127 	MEDIUM_STRENGTH,
128 	HIGH_STRENGTH,
129 	STRENGTH_NUM
130 };
131 
132 #define SHARPEN_ON (1)
133 
134 struct filter_strength vpp_strength[STRENGTH_NUM] = {
135 	[LOW_STRENGTH] = {
136 		/* structure:
137 		 * type(0-Denoise,1-Deblock), value_thr, cnt_thr, coef, temp_thr1, temp_thr2, _pad[2]
138 		 */
139 		.denoise_deblock = {
140 			[QCIF_TO_QVGA]    = {1, 15, 47, 35, 0, 0, {0, 0}},
141 			[QVGA_TO_VGA]     = {0, 7,  48, 47, 0, 0, {0, 0}},
142 			[VGA_TO_SD]       = {0, 10, 8,  9,  1, 3, {0, 0}},
143 			[SD_TO_720P]      = {0, 10, 48, 47, 0, 0, {0, 0}},
144 			[HD720P_TO_1080P] = {0, 10, 48, 47, 0, 0, {0, 0}}
145 		},
146 		/* structure:
147 		 * temp_detect, temp_correct, clip_thr, mid_thr, luma_amm, chroma_amm, _pad[2]
148 		 */
149 		.enhancer = {
150 			[QCIF_TO_QVGA]    = {200, 100, 1, 42, 40, 60, {0, 0}},
151 			[QVGA_TO_VGA]     = {220, 180, 1, 42, 40, 60, {0, 0}},
152 			[VGA_TO_SD]       = {220, 200, 1, 42, 40, 60, {0, 0}},
153 			[SD_TO_720P]      = {100, 100, 5, 33, 0,  0,  {0, 0}},
154 			[HD720P_TO_1080P] = {100, 100, 5, 33, 0,  0,  {0, 0}}
155 		},
156 		.sharpen = {
157 			[QCIF_TO_QVGA]    = { .quality = SHARPEN_ON },
158 			[QVGA_TO_VGA]     = { .quality = SHARPEN_ON },
159 			[VGA_TO_SD]       = { .quality = SHARPEN_ON },
160 			[SD_TO_720P]      = { .quality = SHARPEN_ON },
161 			[HD720P_TO_1080P] = { .quality = SHARPEN_ON }
162 		}
163 	},
164 	[MEDIUM_STRENGTH] = {
165 		.denoise_deblock = {
166 			[QCIF_TO_QVGA]    = {1, 25, 47, 12, 0, 0, {0, 0}},
167 			[QVGA_TO_VGA]     = {0, 10, 48, 47, 0, 0, {0, 0}},
168 			[VGA_TO_SD]       = {0, 20, 8,  9,  2, 4, {0, 0}},
169 			[SD_TO_720P]      = {0, 10, 48, 47, 0, 0, {0, 0}},
170 			[HD720P_TO_1080P] = {0, 10, 48, 47, 0, 0, {0, 0}}
171 		},
172 		.enhancer = {
173 			[QCIF_TO_QVGA]    = {100, 100, 1, 33, 100, 100, {0, 0}},
174 			[QVGA_TO_VGA]     = {100, 180, 1, 33, 100, 100, {0, 0}},
175 			[VGA_TO_SD]       = {100, 200, 1, 33, 100, 100, {0, 0}},
176 			[SD_TO_720P]      = {100, 100, 5, 33, 0,   0,   {0, 0}},
177 			[HD720P_TO_1080P] = {100, 100, 5, 33, 0,   0,   {0, 0}}
178 		},
179 		.sharpen = {
180 			[QCIF_TO_QVGA]    = { .quality = SHARPEN_ON },
181 			[QVGA_TO_VGA]     = { .quality = SHARPEN_ON },
182 			[VGA_TO_SD]       = { .quality = SHARPEN_ON },
183 			[SD_TO_720P]      = { .quality = SHARPEN_ON },
184 			[HD720P_TO_1080P] = { .quality = SHARPEN_ON }
185 		}
186 	},
187 	[HIGH_STRENGTH] = {
188 		.denoise_deblock = {
189 			[QCIF_TO_QVGA]    = {1, 30, 40, 10, 0, 0, {0, 0}},
190 			[QVGA_TO_VGA]     = {0, 15, 45, 25, 0, 0, {0, 0}},
191 			[VGA_TO_SD]       = {0, 20, 7,  5,  3, 6, {0, 0}},
192 			[SD_TO_720P]      = {0, 10, 48, 47, 0, 0, {0, 0}},
193 			[HD720P_TO_1080P] = {0, 10, 48, 47, 0, 0, {0, 0}}
194 		},
195 		.enhancer = {
196 			[QCIF_TO_QVGA]    = {100, 100, 5, 33, 150, 200, {0, 0}},
197 			[QVGA_TO_VGA]     = {100, 180, 5, 33, 150, 200, {0, 0}},
198 			[VGA_TO_SD]       = {100, 200, 5, 33, 100, 150, {0, 0}},
199 			[SD_TO_720P]      = {100, 100, 5, 33, 0,   0,   {0, 0}},
200 			[HD720P_TO_1080P] = {100, 100, 5, 33, 0,   0,   {0, 0}}
201 		},
202 		.sharpen = {
203 			[QCIF_TO_QVGA]    = { .quality = SHARPEN_ON },
204 			[QVGA_TO_VGA]     = { .quality = SHARPEN_ON },
205 			[VGA_TO_SD]       = { .quality = SHARPEN_ON },
206 			[SD_TO_720P]      = { .quality = SHARPEN_ON },
207 			[HD720P_TO_1080P] = { .quality = SHARPEN_ON }
208 		}
209 	}
210 };
211 
212 static void vsp_VPP_DestroyContext(object_context_p obj_context);
213 static VAStatus vsp_set_pipeline(context_VPP_p ctx);
214 static VAStatus vsp_set_filter_param(context_VPP_p ctx);
215 static VAStatus vsp__VPP_check_legal_picture(object_context_p obj_context, object_config_p obj_config);
216 static int check_resolution(int width, int height);
217 static int check_vpp_strength(int value);
218 
vsp_VPP_QueryConfigAttributes(VAProfile __maybe_unused profile,VAEntrypoint __maybe_unused entrypoint,VAConfigAttrib __maybe_unused * attrib_list,int __maybe_unused num_attribs)219 static void vsp_VPP_QueryConfigAttributes(
220 	VAProfile __maybe_unused profile,
221 	VAEntrypoint __maybe_unused entrypoint,
222 	VAConfigAttrib __maybe_unused *attrib_list,
223 	int __maybe_unused num_attribs)
224 {
225 	/* No VPP specific attributes */
226 	return;
227 }
228 
vsp_VPP_ValidateConfig(object_config_p obj_config)229 static VAStatus vsp_VPP_ValidateConfig(
230 	object_config_p obj_config)
231 {
232 	int i;
233 	/* Check all attributes */
234 	for (i = 0; i < obj_config->attrib_count; i++) {
235 		switch (obj_config->attrib_list[i].type) {
236 		case VAConfigAttribRTFormat:
237 			/* Ignore */
238 			break;
239 
240 		default:
241 			return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
242 		}
243 	}
244 
245 	return VA_STATUS_SUCCESS;
246 }
247 
vsp__VPP_check_legal_picture(object_context_p obj_context,object_config_p obj_config)248 static VAStatus vsp__VPP_check_legal_picture(object_context_p obj_context, object_config_p obj_config)
249 {
250 	VAStatus vaStatus = VA_STATUS_SUCCESS;
251 
252 	if (NULL == obj_context) {
253 		vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
254 		DEBUG_FAILURE;
255 		return vaStatus;
256 	}
257 
258 	if (NULL == obj_config) {
259 		vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
260 		DEBUG_FAILURE;
261 		return vaStatus;
262 	}
263 
264 	return vaStatus;
265 }
266 
vsp_VPP_CreateContext(object_context_p obj_context,object_config_p obj_config)267 static VAStatus vsp_VPP_CreateContext(
268 	object_context_p obj_context,
269 	object_config_p obj_config)
270 {
271 	VAStatus vaStatus = VA_STATUS_SUCCESS;
272 	context_VPP_p ctx;
273 	int i;
274 
275 	/* Validate flag */
276 	/* Validate picture dimensions */
277 	vaStatus = vsp__VPP_check_legal_picture(obj_context, obj_config);
278 	if (VA_STATUS_SUCCESS != vaStatus) {
279 		DEBUG_FAILURE;
280 		return vaStatus;
281 	}
282 
283 	ctx = (context_VPP_p) calloc(1, sizeof(struct context_VPP_s));
284 	if (NULL == ctx) {
285 		vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
286 		DEBUG_FAILURE;
287 		return vaStatus;
288 	}
289 
290 	ctx->filters = NULL;
291 	ctx->num_filters = 0;
292 
293 	ctx->frc_buf = NULL;
294 
295 	/* set size */
296 	ctx->param_sz = 0;
297 	ctx->pic_param_sz = ALIGN_TO_128(sizeof(struct VssProcPictureParameterBuffer));
298 	ctx->param_sz += ctx->pic_param_sz;
299 	ctx->end_param_sz = ALIGN_TO_128(sizeof(struct VssProcPictureParameterBuffer));
300 	ctx->param_sz += ctx->end_param_sz;
301 
302 	ctx->pipeline_param_sz = ALIGN_TO_128(sizeof(struct VssProcPipelineParameterBuffer));
303 	ctx->param_sz += ctx->pipeline_param_sz;
304 	ctx->denoise_param_sz = ALIGN_TO_128(sizeof(struct VssProcDenoiseParameterBuffer));
305 	ctx->param_sz += ctx->denoise_param_sz;
306 	ctx->enhancer_param_sz = ALIGN_TO_128(sizeof(struct VssProcColorEnhancementParameterBuffer));
307 	ctx->param_sz += ctx->enhancer_param_sz;
308 	ctx->sharpen_param_sz = ALIGN_TO_128(sizeof(struct VssProcSharpenParameterBuffer));
309 	ctx->param_sz += ctx->sharpen_param_sz;
310 	ctx->frc_param_sz = ALIGN_TO_128(sizeof(struct VssProcFrcParameterBuffer));
311 	ctx->param_sz += ctx->frc_param_sz;
312 	ctx->compose_param_sz = ALIGN_TO_128(sizeof(struct VssWiDi_ComposeSequenceParameterBuffer));
313 	ctx->param_sz += ctx->compose_param_sz;
314 
315 	/* set offset */
316 	ctx->pic_param_offset = 0;
317 	ctx->end_param_offset = ctx->pic_param_offset + ctx->pic_param_sz;
318 	ctx->pipeline_param_offset = ctx->end_param_offset + ctx->end_param_sz;
319 	ctx->denoise_param_offset = ctx->pipeline_param_offset + ctx->pipeline_param_sz;
320 	ctx->enhancer_param_offset = ctx->denoise_param_offset + ctx->denoise_param_sz;
321 	ctx->sharpen_param_offset = ctx->enhancer_param_offset + ctx->enhancer_param_sz;
322 	ctx->frc_param_offset = ctx->sharpen_param_offset + ctx->sharpen_param_sz;
323 	/* For composer, it'll start on 0 */
324 	ctx->compose_param_offset = 0;
325 
326 	/* create intermediate buffer */
327 	ctx->intermediate_buf = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s));
328 	if (NULL == ctx->intermediate_buf) {
329 		vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
330 		DEBUG_FAILURE;
331 		goto out;
332 	}
333 	vaStatus = psb_buffer_create(obj_context->driver_data, VSP_INTERMEDIATE_BUF_SIZE, psb_bt_vpu_only, ctx->intermediate_buf);
334 	if (VA_STATUS_SUCCESS != vaStatus) {
335 		goto out;
336 	}
337 
338 	obj_context->format_data = (void*) ctx;
339 	ctx->obj_context = obj_context;
340 
341 	for (i = 0; i < obj_config->attrib_count; ++i) {
342 		if (VAConfigAttribRTFormat == obj_config->attrib_list[i].type) {
343 			switch (obj_config->attrib_list[i].value) {
344 			case VA_RT_FORMAT_YUV420:
345 				ctx->format = VSP_NV12;
346 				break;
347 			case VA_RT_FORMAT_YUV422:
348 				ctx->format = VSP_NV16;
349 			default:
350 				ctx->format = VSP_NV12;
351 				break;
352 			}
353 			break;
354 		}
355 	}
356 
357 	bzero(&ctx->denoise_deblock_param, sizeof(ctx->denoise_deblock_param));
358 	bzero(&ctx->enhancer_param, sizeof(ctx->enhancer_param));
359 	bzero(&ctx->sharpen_param, sizeof(ctx->sharpen_param));
360 
361 	return vaStatus;
362 out:
363 	vsp_VPP_DestroyContext(obj_context);
364 
365     if (ctx) {
366         if(ctx->intermediate_buf != NULL)
367             free(ctx->intermediate_buf);
368         free(ctx);
369         ctx = NULL;
370     }
371 
372 	return vaStatus;
373 }
374 
vsp_VPP_DestroyContext(object_context_p obj_context)375 static void vsp_VPP_DestroyContext(
376 	object_context_p obj_context)
377 {
378 	INIT_CONTEXT_VPP;
379 
380 	if (ctx->intermediate_buf) {
381 		psb_buffer_destroy(ctx->intermediate_buf);
382 
383 		free(ctx->intermediate_buf);
384 		ctx->intermediate_buf = NULL;
385 	}
386 
387 	if (ctx->filters) {
388 		free(ctx->filters);
389 		ctx->num_filters = 0;
390 	}
391 
392 	free(obj_context->format_data);
393 	obj_context->format_data = NULL;
394 }
395 
vsp__VPP_process_pipeline_param(context_VPP_p ctx,object_context_p obj_context,object_buffer_p obj_buffer)396 static VAStatus vsp__VPP_process_pipeline_param(context_VPP_p ctx, object_context_p obj_context, object_buffer_p obj_buffer)
397 {
398 	VAStatus vaStatus = VA_STATUS_SUCCESS;
399 	vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf;
400 	unsigned int i = 0;
401 	VAProcPipelineParameterBuffer *pipeline_param = (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data;
402 	struct VssProcPictureParameterBuffer *cell_proc_picture_param = (struct VssProcPictureParameterBuffer *)cmdbuf->pic_param_p;
403 	struct VssProcPictureParameterBuffer *cell_end_param = (struct VssProcPictureParameterBuffer *)cmdbuf->end_param_p;
404 	VAProcFilterParameterBufferFrameRateConversion *frc_param;
405 	object_surface_p input_surface = NULL;
406 	object_surface_p cur_output_surf = NULL;
407 	unsigned int rotation_angle = 0, vsp_rotation_angle = 0;
408 	unsigned int tiled = 0, width = 0, height = 0, stride = 0;
409 	unsigned char *src_addr, *dest_addr;
410 	struct psb_surface_s *output_surface;
411 	psb_surface_share_info_p input_share_info = NULL;
412 	psb_surface_share_info_p output_share_info = NULL;
413  	enum vsp_format format;
414 
415 
416 	psb_driver_data_p driver_data = obj_context->driver_data;
417 
418 	if (pipeline_param->surface_region != NULL) {
419 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Cann't scale\n");
420 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
421 		goto out;
422 	}
423 
424 	if (pipeline_param->output_region != NULL) {
425 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Cann't scale\n");
426 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
427 		goto out;
428 	}
429 
430 	if (pipeline_param->output_background_color != 0) {
431 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Cann't support background color here\n");
432 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
433 		goto out;
434 	}
435 
436 	if (pipeline_param->filters == NULL) {
437 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filter setting filters = %p\n", pipeline_param->filters);
438 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
439 		goto out;
440 	}
441 
442 #if 0
443 	/* for pass filter */
444 	if (pipeline_param->num_filters == 0 || pipeline_param->num_filters > VssProcPipelineMaxNumFilters) {
445 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filter number = %d\n", pipeline_param->num_filters);
446 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
447 		goto out;
448 	}
449 #endif
450 
451 	if (pipeline_param->forward_references == NULL) {
452 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid forward_refereces %p setting\n", pipeline_param->forward_references);
453 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
454 		goto out;
455 	}
456 
457 	/* should we check it? since the begining it's not VSP_FORWARD_REF_NUM */
458 	if (pipeline_param->num_forward_references != VSP_FORWARD_REF_NUM) {
459 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_forward_refereces %d setting, should be %d\n", pipeline_param->num_forward_references, VSP_FORWARD_REF_NUM);
460 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
461 		goto out;
462 	}
463 
464 	/* first picture, need to setup the VSP context */
465 	if (ctx->obj_context->frame_count == 0)
466 		vsp_cmdbuf_vpp_context(cmdbuf, VssGenInitializeContext, CONTEXT_VPP_ID, VSP_APP_ID_FRC_VPP);
467 
468 	/* get the input surface */
469 	if (!(pipeline_param->pipeline_flags & VA_PIPELINE_FLAG_END)) {
470 		input_surface = SURFACE(pipeline_param->surface);
471 		if (input_surface == NULL) {
472 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid input surface %x\n", pipeline_param->surface);
473 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
474 			goto out;
475 		}
476 	} else {
477 		input_surface = NULL;
478 	}
479 
480 	/* if it is the first pipeline command */
481 	if (pipeline_param->num_filters != ctx->num_filters || pipeline_param->num_filters == 0) {
482 		if (ctx->num_filters != 0) {
483 			drv_debug_msg(VIDEO_DEBUG_ERROR, "can not reset pipeline in the mid of post-processing or without create a new context\n");
484 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
485 			goto out;
486 		} else {
487 			/* save filters */
488 			ctx->num_filters = pipeline_param->num_filters;
489 			if (ctx->num_filters == 0) {
490 				ctx->filters = NULL;
491 			} else {
492 				ctx->filters = (VABufferID *) calloc(ctx->num_filters, sizeof(*ctx->filters));
493 				if (ctx->filters == NULL) {
494 					drv_debug_msg(VIDEO_DEBUG_ERROR, "can not reset pipeline in the mid of post-processing or without create a new context\n");
495 					vaStatus = VA_STATUS_ERROR_UNKNOWN;
496 					goto out;
497 				}
498 				memcpy(ctx->filters, pipeline_param->filters, ctx->num_filters * sizeof(*ctx->filters));
499 			}
500 
501 			/* set pipeline command to FW */
502 			vaStatus = vsp_set_pipeline(ctx);
503 			if (vaStatus) {
504 				drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to set pipeline\n");
505 				goto out;
506 			}
507 
508 			/* set filter parameter to FW, record frc parameter buffer */
509 			vaStatus = vsp_set_filter_param(ctx);
510 			if (vaStatus) {
511 				drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to set filter parameter\n");
512 				goto out;
513 			}
514 		}
515 	} else {
516 		/* else ignore pipeline/filter setting  */
517 #if 0
518 		/* FIXME: we can save these check for PnP */
519 		for (i = 0; i < pipeline_param->num_filters; i++) {
520 			if (pipeline_param->filters[i] != ctx->filters[i]) {
521 				drv_debug_msg(VIDEO_DEBUG_ERROR, "can not reset pipeline in the mid of post-processing or without create a new context\n");
522 				vaStatus = VA_STATUS_ERROR_UNKNOWN;
523 				goto out;
524 			}
525 		}
526 #endif
527 	}
528 
529 	/* fill picture command to FW */
530 	if (ctx->frc_buf != NULL)
531 		frc_param = (VAProcFilterParameterBufferFrameRateConversion *)ctx->frc_buf->buffer_data;
532 	else
533 		frc_param = NULL;
534 
535 	/* end picture command */
536 	if (pipeline_param->pipeline_flags & VA_PIPELINE_FLAG_END) {
537 		cell_end_param->num_input_pictures = 0;
538 		cell_end_param->num_output_pictures = 0;
539 		vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VPP_ID, &cmdbuf->param_mem, VssProcPictureCommand,
540 					  ctx->end_param_offset, sizeof(struct VssProcPictureParameterBuffer));
541 		/* Destory the VSP context */
542 		vsp_cmdbuf_vpp_context(cmdbuf, VssGenDestroyContext, CONTEXT_VPP_ID, 0);
543 		goto out;
544 	}
545 
546 #ifdef PSBVIDEO_VPP_TILING
547 	/* get the tiling flag*/
548 	tiled = GET_SURFACE_INFO_tiling(input_surface->psb_surface);
549 #endif
550 
551 	/* get the surface format info  */
552 	switch (input_surface->psb_surface->extra_info[8]) {
553 		case VA_FOURCC_YV12:
554 			format = VSP_YV12;
555 			break;
556 		case VA_FOURCC_NV12:
557 			format = VSP_NV12;
558 			break;
559 		default:
560 			vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
561 			drv_debug_msg(VIDEO_DEBUG_ERROR, "Only support NV12 and YV12 format!\n");
562 			goto out;
563 	}
564 
565 	/*  According to VIED's design, the width must be multiple of 16 */
566 	width = ALIGN_TO_16(input_surface->width);
567 	if (width > input_surface->psb_surface->stride)
568 		width = input_surface->psb_surface->stride;
569 
570 	/* get the input share info */
571 	input_share_info = input_surface->share_info;
572 	drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s The input surface %p share info %p\n", __func__, input_surface,input_surface->share_info);
573 
574 	/* Setup input surface */
575 	cell_proc_picture_param->num_input_pictures  = 1;
576 	cell_proc_picture_param->input_picture[0].surface_id = pipeline_param->surface;
577 	vsp_cmdbuf_reloc_pic_param(&(cell_proc_picture_param->input_picture[0].base), ctx->pic_param_offset, &(input_surface->psb_surface->buf),
578 				   cmdbuf->param_mem_loc, cell_proc_picture_param);
579 	cell_proc_picture_param->input_picture[0].height = input_surface->height;
580 	cell_proc_picture_param->input_picture[0].width = width;
581 	cell_proc_picture_param->input_picture[0].irq = 0;
582 	cell_proc_picture_param->input_picture[0].stride = input_surface->psb_surface->stride;
583 	cell_proc_picture_param->input_picture[0].format = format;
584 	cell_proc_picture_param->input_picture[0].tiled = tiled;
585 	cell_proc_picture_param->input_picture[0].rot_angle = 0;
586 
587 	/* Setup output surfaces */
588 	if (frc_param == NULL)
589 		cell_proc_picture_param->num_output_pictures = 1;
590 	else
591 		cell_proc_picture_param->num_output_pictures = frc_param->num_output_frames + 1;
592 
593 	for (i = 0; i < cell_proc_picture_param->num_output_pictures; ++i) {
594 		if (i == 0) {
595 			cur_output_surf = ctx->obj_context->current_render_target;
596 
597 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
598 			/* The rotation info is saved in the first frame */
599 			rotation_angle = GET_SURFACE_INFO_rotate(cur_output_surf->psb_surface);
600 			switch (rotation_angle) {
601 				case VA_ROTATION_90:
602 					vsp_rotation_angle = VSP_ROTATION_90;
603 					break;
604 				case VA_ROTATION_180:
605 					vsp_rotation_angle = VSP_ROTATION_180;
606 					break;
607 				case VA_ROTATION_270:
608 					vsp_rotation_angle = VSP_ROTATION_270;
609 					break;
610 				default:
611 					vsp_rotation_angle = VSP_ROTATION_NONE;
612 			}
613 #endif
614 		} else {
615 			if (frc_param == NULL) {
616 				drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid output surface numbers %x\n",
617 					      cell_proc_picture_param->num_output_pictures);
618 				vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
619 				goto out;
620 			}
621 
622 			cur_output_surf = SURFACE(frc_param->output_frames[i-1]);
623 			if (cur_output_surf == NULL) {
624 				drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid input surface %x\n", frc_param->output_frames[i-1]);
625 				vaStatus = VA_STATUS_ERROR_UNKNOWN;
626 				goto out;
627 			}
628 
629 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
630 			/* VPP rotation is just for 1080P */
631 			if (tiled && rotation_angle != VA_ROTATION_NONE) {
632 				if (VA_STATUS_SUCCESS != psb_CreateRotateSurface(obj_context, cur_output_surf, rotation_angle)) {
633 					drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to alloc rotation surface!\n");
634 					vaStatus = VA_STATUS_ERROR_UNKNOWN;
635 					goto out;
636 				}
637 			}
638 #endif
639 		}
640 
641 		if (tiled && rotation_angle != VA_ROTATION_NONE) {
642 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
643 			/* For 90d and 270d, we need to alloc rotation buff and
644 			 * copy the 0d data from input to output
645 			 */
646 			psb_buffer_map(&(input_surface->psb_surface->buf), &src_addr);
647 			psb_buffer_map(&(cur_output_surf->psb_surface->buf), &dest_addr);
648 			memcpy(dest_addr, src_addr, cur_output_surf->psb_surface->size);
649 			psb_buffer_unmap(&(cur_output_surf->psb_surface->buf));
650 			psb_buffer_unmap(&(input_surface->psb_surface->buf));
651 
652 			output_surface = cur_output_surf->out_loop_surface;
653 
654 			/*  According to VIED's design, the width must be multiple of 16 */
655 			width = ALIGN_TO_16(cur_output_surf->height_origin);
656 			if (width > cur_output_surf->out_loop_surface->stride)
657 				width = cur_output_surf->out_loop_surface->stride;
658 			height = cur_output_surf->width;
659 			stride = cur_output_surf->out_loop_surface->stride;
660 #endif
661 		} else {
662 			output_surface = cur_output_surf->psb_surface;
663 
664 			/*  According to VIED's design, the width must be multiple of 16 */
665 			width = ALIGN_TO_16(cur_output_surf->width);
666 			if (width > cur_output_surf->psb_surface->stride)
667 				width = cur_output_surf->psb_surface->stride;
668 			height = cur_output_surf->height;
669 			stride = cur_output_surf->psb_surface->stride;
670 
671 			/* Check the rotate bit */
672 			if (pipeline_param->rotation_state == VA_ROTATION_90)
673 				vsp_rotation_angle = VSP_ROTATION_90;
674 			else if (pipeline_param->rotation_state == VA_ROTATION_180)
675 				vsp_rotation_angle = VSP_ROTATION_180;
676 			else if (pipeline_param->rotation_state == VA_ROTATION_270)
677 				vsp_rotation_angle = VSP_ROTATION_270;
678 			else
679 				vsp_rotation_angle = VSP_ROTATION_NONE;
680 		}
681 
682 		cell_proc_picture_param->output_picture[i].surface_id = wsbmKBufHandle(wsbmKBuf(output_surface->buf.drm_buf));
683 
684 		vsp_cmdbuf_reloc_pic_param(&(cell_proc_picture_param->output_picture[i].base),
685 					   ctx->pic_param_offset, &(output_surface->buf),
686 					   cmdbuf->param_mem_loc, cell_proc_picture_param);
687 		cell_proc_picture_param->output_picture[i].height = height;
688 		cell_proc_picture_param->output_picture[i].width = width;
689 		cell_proc_picture_param->output_picture[i].stride = stride;
690 		cell_proc_picture_param->output_picture[i].irq = 1;
691 		cell_proc_picture_param->output_picture[i].format = format;
692 		cell_proc_picture_param->output_picture[i].rot_angle = vsp_rotation_angle;
693 		cell_proc_picture_param->output_picture[i].tiled = tiled;
694 
695 		/* copy the input share info to output */
696 		output_share_info = cur_output_surf->share_info;
697 		if (input_share_info != NULL && output_share_info != NULL) {
698             output_share_info->native_window = input_share_info->native_window;
699             output_share_info->force_output_method = input_share_info->force_output_method;
700             output_share_info->surface_protected = input_share_info->surface_protected;
701             output_share_info->bob_deinterlace = input_share_info->bob_deinterlace;
702 
703             output_share_info->crop_width = input_share_info->crop_width;
704             output_share_info->crop_height = input_share_info->crop_height;
705             output_share_info->coded_width = input_share_info->coded_width;
706             output_share_info->coded_height = input_share_info->coded_height;
707 			drv_debug_msg(VIDEO_DEBUG_GENERAL, "The input/output wxh %dx%d\n",input_share_info->width,input_share_info->height);
708 		} else {
709 			drv_debug_msg(VIDEO_DEBUG_WARNING, "The input/output share_info is NULL!!\n");
710 		}
711 	}
712 
713 	vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VPP_ID, &cmdbuf->param_mem, VssProcPictureCommand,
714 				  ctx->pic_param_offset, sizeof(struct VssProcPictureParameterBuffer));
715 
716 	vsp_cmdbuf_fence_pic_param(cmdbuf, wsbmKBufHandle(wsbmKBuf(cmdbuf->param_mem.drm_buf)));
717 
718 #if 0
719 	/* handle reference frames, ignore backward reference */
720 	for (i = 0; i < pipeline_param->num_forward_references; ++i) {
721 		cur_output_surf = SURFACE(pipeline_param->forward_references[i]);
722 		if (cur_output_surf == NULL)
723 			continue;
724 		if (vsp_cmdbuf_buffer_ref(cmdbuf, &cur_output_surf->psb_surface->buf) < 0) {
725 			drv_debug_msg(VIDEO_DEBUG_ERROR, "vsp_cmdbuf_buffer_ref() failed\n");
726 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
727 			goto out;
728 		}
729 	}
730 #endif
731 out:
732 	free(pipeline_param);
733 	obj_buffer->buffer_data = NULL;
734 	obj_buffer->size = 0;
735 
736 	return vaStatus;
737 }
738 
vsp_VPP_RenderPicture(object_context_p obj_context,object_buffer_p * buffers,int num_buffers)739 static VAStatus vsp_VPP_RenderPicture(
740 	object_context_p obj_context,
741 	object_buffer_p *buffers,
742 	int num_buffers)
743 {
744 	int i;
745 	INIT_CONTEXT_VPP;
746 	VAProcPipelineParameterBuffer *pipeline_param = NULL;
747 	VAStatus vaStatus = VA_STATUS_SUCCESS;
748 
749 	for (i = 0; i < num_buffers; i++) {
750 		object_buffer_p obj_buffer = buffers[i];
751 		pipeline_param = (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data;
752 
753 		switch (obj_buffer->type) {
754 		case VAProcPipelineParameterBufferType:
755 			if (!pipeline_param->num_filters && pipeline_param->blend_state)
756 				/* For Security Composer */
757 				vaStatus = vsp_compose_process_pipeline_param(ctx, obj_context, obj_buffer);
758 			else
759 				/* For VPP/FRC */
760 				vaStatus = vsp__VPP_process_pipeline_param(ctx, obj_context, obj_buffer);
761 			DEBUG_FAILURE;
762 			break;
763 		default:
764 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
765 			DEBUG_FAILURE;
766 		}
767 		if (vaStatus != VA_STATUS_SUCCESS) {
768 			break;
769 		}
770 	}
771 
772 	return vaStatus;
773 }
774 
vsp_VPP_BeginPicture(object_context_p obj_context)775 static VAStatus vsp_VPP_BeginPicture(
776 	object_context_p obj_context)
777 {
778 	int ret;
779 	VAStatus vaStatus = VA_STATUS_SUCCESS;
780 	INIT_CONTEXT_VPP;
781 	vsp_cmdbuf_p cmdbuf;
782 
783 	/* Initialise the command buffer */
784 	ret = vsp_context_get_next_cmdbuf(ctx->obj_context);
785 	if (ret) {
786 		drv_debug_msg(VIDEO_DEBUG_GENERAL, "get next cmdbuf fail\n");
787 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
788 		return vaStatus;
789 	}
790 
791 	cmdbuf = obj_context->vsp_cmdbuf;
792 
793 	/* map param mem */
794 	vaStatus = psb_buffer_map(&cmdbuf->param_mem, &cmdbuf->param_mem_p);
795 	if (vaStatus) {
796 		return vaStatus;
797 	}
798 
799 	cmdbuf->pic_param_p = cmdbuf->param_mem_p + ctx->pic_param_offset;
800 	cmdbuf->end_param_p = cmdbuf->param_mem_p + ctx->end_param_offset;
801 	cmdbuf->pipeline_param_p = cmdbuf->param_mem_p + ctx->pipeline_param_offset;
802 	cmdbuf->denoise_param_p = cmdbuf->param_mem_p + ctx->denoise_param_offset;
803 	cmdbuf->enhancer_param_p = cmdbuf->param_mem_p + ctx->enhancer_param_offset;
804 	cmdbuf->sharpen_param_p = cmdbuf->param_mem_p + ctx->sharpen_param_offset;
805 	cmdbuf->frc_param_p = cmdbuf->param_mem_p + ctx->frc_param_offset;
806 	cmdbuf->compose_param_p = cmdbuf->param_mem_p + ctx->compose_param_offset;
807 
808 	return VA_STATUS_SUCCESS;
809 }
810 
vsp_VPP_EndPicture(object_context_p obj_context)811 static VAStatus vsp_VPP_EndPicture(
812 	object_context_p obj_context)
813 {
814 	INIT_CONTEXT_VPP;
815 	psb_driver_data_p driver_data = obj_context->driver_data;
816 	vsp_cmdbuf_p cmdbuf = obj_context->vsp_cmdbuf;
817 
818 	if(cmdbuf->param_mem_p != NULL) {
819 		psb_buffer_unmap(&cmdbuf->param_mem);
820 		cmdbuf->param_mem_p = NULL;
821 		cmdbuf->pic_param_p = NULL;
822 		cmdbuf->end_param_p = NULL;
823 		cmdbuf->pipeline_param_p = NULL;
824 		cmdbuf->denoise_param_p = NULL;
825 		cmdbuf->enhancer_param_p = NULL;
826 		cmdbuf->sharpen_param_p = NULL;
827 		cmdbuf->frc_param_p = NULL;
828 		cmdbuf->compose_param_p = NULL;
829 	}
830 
831 	if (vsp_context_flush_cmdbuf(ctx->obj_context)) {
832 		drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_VPP: flush deblock cmdbuf error\n");
833 		return VA_STATUS_ERROR_UNKNOWN;
834 	}
835 
836 	return VA_STATUS_SUCCESS;
837 }
838 
839 struct format_vtable_s vsp_VPP_vtable = {
840 queryConfigAttributes:
841 vsp_VPP_QueryConfigAttributes,
842 validateConfig:
843 vsp_VPP_ValidateConfig,
844 createContext:
845 vsp_VPP_CreateContext,
846 destroyContext:
847 vsp_VPP_DestroyContext,
848 beginPicture:
849 vsp_VPP_BeginPicture,
850 renderPicture:
851 vsp_VPP_RenderPicture,
852 endPicture:
853 vsp_VPP_EndPicture
854 };
855 
vsp_QueryVideoProcFilters(VADriverContextP ctx,VAContextID context,VAProcFilterType * filters,unsigned int * num_filters)856 VAStatus vsp_QueryVideoProcFilters(
857 	VADriverContextP    ctx,
858 	VAContextID         context,
859 	VAProcFilterType   *filters,
860 	unsigned int       *num_filters
861 	)
862 {
863 	INIT_DRIVER_DATA;
864 	VAStatus vaStatus = VA_STATUS_SUCCESS;
865 	object_context_p obj_context;
866 	object_config_p obj_config;
867 	VAEntrypoint tmp;
868 	int count;
869 
870 	/* check if ctx is right */
871 	obj_context = CONTEXT(context);
872 	if (NULL == obj_context) {
873 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
874 		vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
875 		goto err;
876 	}
877 
878 	obj_config = CONFIG(obj_context->config_id);
879 	if (NULL == obj_config) {
880 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
881 		vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
882 		goto err;
883 	}
884 
885 	tmp = obj_config->entrypoint;
886 	if (tmp != VAEntrypointVideoProc) {
887 		drv_debug_msg(VIDEO_DEBUG_ERROR, "current entrypoint is %d, not VAEntrypointVideoProc\n", tmp);
888 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
889 		goto err;
890 	}
891 
892 	/* check if filters and num_filters is valid */
893 	if (NULL == num_filters || NULL == filters) {
894 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filters, filters);
895 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
896 		goto err;
897 	}
898 
899 	/* check if the filter array size is valid */
900 	if (*num_filters < VSP_SUPPORTED_FILTERS_NUM) {
901 		drv_debug_msg(VIDEO_DEBUG_ERROR, "The filters array size(%d) is NOT valid! Supported filters num is %d\n",
902 				*num_filters, VSP_SUPPORTED_FILTERS_NUM);
903 		vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
904 		*num_filters = VSP_SUPPORTED_FILTERS_NUM;
905 		goto err;
906 	}
907 
908 	/* check if current HW support Video proc */
909 	if (IS_MRFL(driver_data)) {
910 		count = 0;
911 		filters[count++] = VAProcFilterDeblocking;
912 		filters[count++] = VAProcFilterNoiseReduction;
913 		filters[count++] = VAProcFilterSharpening;
914 		filters[count++] = VAProcFilterColorBalance;
915 		filters[count++] = VAProcFilterFrameRateConversion;
916 		*num_filters = count;
917 	} else {
918 		*num_filters = 0;
919 	}
920 err:
921 	return vaStatus;
922 }
923 
vsp_QueryVideoProcFilterCaps(VADriverContextP ctx,VAContextID context,VAProcFilterType type,void * filter_caps,unsigned int * num_filter_caps)924 VAStatus vsp_QueryVideoProcFilterCaps(
925 	VADriverContextP    ctx,
926 	VAContextID         context,
927 	VAProcFilterType    type,
928 	void               *filter_caps,
929 	unsigned int       *num_filter_caps
930 	)
931 {
932 	INIT_DRIVER_DATA;
933 	VAStatus vaStatus = VA_STATUS_SUCCESS;
934 	object_context_p obj_context;
935 	object_config_p obj_config;
936 	VAEntrypoint tmp;
937 	VAProcFilterCap *denoise_cap, *deblock_cap;
938 	VAProcFilterCap *sharpen_cap;
939 	VAProcFilterCapColorBalance *color_balance_cap;
940 	VAProcFilterCap *frc_cap;
941 
942 	/* check if context is right */
943 	obj_context = CONTEXT(context);
944 	if (NULL == obj_context) {
945 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
946 		vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
947 		goto err;
948 	}
949 
950 	obj_config = CONFIG(obj_context->config_id);
951 	if (NULL == obj_config) {
952 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
953 		vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
954 		goto err;
955 	}
956 
957 	/* check if filter_caps and num_filter_caps is right */
958 	if (NULL == num_filter_caps || NULL == filter_caps){
959 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filter_caps, filter_caps);
960 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
961 		goto err;
962 	}
963 
964 	if (*num_filter_caps < 1) {
965 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters == %d (> 1)\n", *num_filter_caps);
966 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
967 		goto err;
968 	}
969 
970 	/* check if curent HW support and return corresponding caps */
971 	if (IS_MRFL(driver_data)) {
972 		/* FIXME: we should use a constant table to return caps */
973 		switch (type) {
974 		case VAProcFilterNoiseReduction:
975 			denoise_cap = filter_caps;
976 			denoise_cap->range.min_value = MIN_VPP_PARAM;
977 			denoise_cap->range.max_value = MAX_VPP_PARAM;
978 			denoise_cap->range.default_value = MIN_VPP_PARAM;
979 			denoise_cap->range.step = STEP_VPP_PARAM;
980 			*num_filter_caps = 1;
981 			break;
982 		case VAProcFilterDeblocking:
983 			deblock_cap = filter_caps;
984 			deblock_cap->range.min_value = MIN_VPP_PARAM;
985 			deblock_cap->range.max_value = MAX_VPP_PARAM;
986 			deblock_cap->range.default_value = MIN_VPP_PARAM;
987 			deblock_cap->range.step = STEP_VPP_PARAM;
988 			*num_filter_caps = 1;
989 			break;
990 
991 		case VAProcFilterSharpening:
992 			sharpen_cap = filter_caps;
993 			sharpen_cap->range.min_value = MIN_VPP_PARAM;
994 			sharpen_cap->range.max_value = MAX_VPP_PARAM;
995 			sharpen_cap->range.default_value = MIN_VPP_PARAM;
996 			sharpen_cap->range.step = STEP_VPP_PARAM;
997 			*num_filter_caps = 1;
998 			break;
999 
1000 		case VAProcFilterColorBalance:
1001 			if (*num_filter_caps < VSP_COLOR_ENHANCE_FEATURES) {
1002 				drv_debug_msg(VIDEO_DEBUG_ERROR, "filter cap num is should big than %d(%d)\n",
1003 					      VSP_COLOR_ENHANCE_FEATURES, *num_filter_caps);
1004 				vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1005 				*num_filter_caps = VSP_COLOR_ENHANCE_FEATURES;
1006 				goto err;
1007 			}
1008 			color_balance_cap = filter_caps;
1009 			color_balance_cap->type = VAProcColorBalanceAutoSaturation;
1010 			color_balance_cap->range.min_value = MIN_VPP_AUTO_PARAM;
1011 			color_balance_cap->range.max_value = MAX_VPP_AUTO_PARAM;
1012 			color_balance_cap->range.default_value = MIN_VPP_AUTO_PARAM;
1013 			color_balance_cap->range.step = STEP_VPP_AUTO_PARAM;
1014 
1015 			color_balance_cap++;
1016 			color_balance_cap->type = VAProcColorBalanceAutoBrightness;
1017 			color_balance_cap->range.min_value = MIN_VPP_AUTO_PARAM;
1018 			color_balance_cap->range.max_value = MAX_VPP_AUTO_PARAM;
1019 			color_balance_cap->range.default_value = MIN_VPP_AUTO_PARAM;
1020 			color_balance_cap->range.step = STEP_VPP_AUTO_PARAM;
1021 
1022 			*num_filter_caps = 2;
1023 			break;
1024 
1025 		case VAProcFilterFrameRateConversion:
1026 			frc_cap = filter_caps;
1027 			frc_cap->range.min_value = 2;
1028 			frc_cap->range.max_value = 4;
1029 			frc_cap->range.default_value = 2;
1030 			/* FIXME: it's a set, step is helpless */
1031 			frc_cap->range.step = 0.5;
1032 			*num_filter_caps = 1;
1033 			break;
1034 
1035 		default:
1036 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide filter type %d\n", type);
1037 			vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1038 			*num_filter_caps = 0;
1039 			goto err;
1040 		}
1041 	} else {
1042 		*num_filter_caps = 0;
1043 	}
1044 
1045 err:
1046 	return vaStatus;
1047 }
1048 
vsp_QueryVideoProcPipelineCaps(VADriverContextP ctx,VAContextID context,VABufferID * filters,unsigned int num_filters,VAProcPipelineCaps * pipeline_caps)1049 VAStatus vsp_QueryVideoProcPipelineCaps(
1050 	VADriverContextP    ctx,
1051 	VAContextID         context,
1052 	VABufferID         *filters,
1053 	unsigned int        num_filters,
1054 	VAProcPipelineCaps *pipeline_caps
1055     )
1056 {
1057 	INIT_DRIVER_DATA;
1058 	VAStatus vaStatus = VA_STATUS_SUCCESS;
1059 	object_context_p obj_context;
1060 	object_config_p obj_config;
1061 	VAEntrypoint tmp;
1062 	unsigned int i, j;
1063 	VAProcFilterParameterBuffer *deblock, *denoise, *sharpen;
1064 	VAProcFilterParameterBufferFrameRateConversion *frc;
1065 	VAProcFilterParameterBufferColorBalance *balance;
1066 	VAProcFilterParameterBufferBase *base;
1067 	object_buffer_p buf;
1068 	uint32_t enabled_brightness, enabled_saturation;
1069 	float ratio;
1070 	int res_set;
1071 	int strength;
1072 	context_VPP_p vpp_ctx;
1073 	int combination_check;
1074 
1075 	/* check if ctx is right */
1076 	obj_context = CONTEXT(context);
1077 	if (NULL == obj_context) {
1078 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
1079 		vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
1080 		goto err;
1081 	}
1082 
1083 	vpp_ctx = (context_VPP_p) obj_context->format_data;
1084 
1085 	obj_config = CONFIG(obj_context->config_id);
1086 	if (NULL == obj_config) {
1087 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
1088 		vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
1089 		goto err;
1090 	}
1091 
1092 	/* Don't check the filter number.
1093 	 * According to VIED's design, without any filter, HW will just copy input data
1094 	 */
1095 #if 0
1096 	if (num_filters == 0) {
1097 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_filters %d\n", num_filters);
1098 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1099 		goto err;
1100 	}
1101 #endif
1102 	if (NULL == filters || pipeline_caps == NULL) {
1103 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filters %p or pipeline_caps %p\n", filters, pipeline_caps);
1104 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1105 		goto err;
1106 	}
1107 
1108 	/* base on HW capability check the filters and return pipeline caps */
1109 	if (IS_MRFL(driver_data)) {
1110 		pipeline_caps->pipeline_flags = 0;
1111 		pipeline_caps->filter_flags = 0;
1112 		pipeline_caps->num_forward_references = VSP_FORWARD_REF_NUM;
1113 		pipeline_caps->num_backward_references = 0;
1114 
1115 		/* check the input color standard */
1116 		if (pipeline_caps->input_color_standards == NULL){
1117 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid input color standard array!\n");
1118 			vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1119 			goto err;
1120 		}
1121 		if (pipeline_caps->num_input_color_standards < COLOR_STANDARDS_NUM) {
1122 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_input_color_standards %d\n", pipeline_caps->num_input_color_standards);
1123 			vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1124 			pipeline_caps->num_input_color_standards = COLOR_STANDARDS_NUM;
1125 			goto err;
1126 		}
1127 		pipeline_caps->input_color_standards[0] = VAProcColorStandardNone;
1128 		pipeline_caps->num_input_color_standards = COLOR_STANDARDS_NUM;
1129 
1130 		/* check the output color standard */
1131 		if (pipeline_caps->output_color_standards == NULL){
1132 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid output color standard array!\n");
1133 			vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1134 			goto err;
1135 		}
1136 		if (pipeline_caps->num_output_color_standards < COLOR_STANDARDS_NUM) {
1137 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_output_color_standards %d\n", pipeline_caps->num_output_color_standards);
1138 			vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1139 			pipeline_caps->num_output_color_standards = COLOR_STANDARDS_NUM;
1140 			goto err;
1141 		}
1142 		pipeline_caps->output_color_standards[0] = VAProcColorStandardNone;
1143 		pipeline_caps->num_output_color_standards = COLOR_STANDARDS_NUM;
1144 
1145 		/* check the resolution */
1146 		res_set = check_resolution(obj_context->picture_width,
1147 					   obj_context->picture_height);
1148 		if (res_set == NOT_SUPPORTED_RESOLUTION) {
1149 			vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
1150 			goto err;
1151 		}
1152 
1153 		/* Blend type */
1154 		pipeline_caps->blend_flags = VA_BLEND_PREMULTIPLIED_ALPHA;
1155 
1156 		if (getenv("VSP_PIPELINE_CHECK") != NULL)
1157 			combination_check = 1;
1158 		else
1159 			combination_check = 0;
1160 
1161 		/* FIXME: should check filter value settings here */
1162 		for (i = 0; i < num_filters; ++i) {
1163 			/* find buffer */
1164 			buf = BUFFER(*(filters + i));
1165 			if (!buf) {
1166 				vaStatus = VA_STATUS_ERROR_UNKNOWN;
1167 				goto err;
1168 			}
1169 
1170 			base = (VAProcFilterParameterBufferBase *)buf->buffer_data;
1171 			/* check filter buffer setting */
1172 			switch (base->type) {
1173 			case VAProcFilterDeblocking:
1174 				deblock = (VAProcFilterParameterBuffer *)base;
1175 
1176 				if (combination_check &&
1177 				    vpp_chain_caps[res_set].deblock_enabled != FILTER_ENABLED) {
1178 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The deblock is DISABLE for %d format\n", res_set);
1179 					vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
1180 					goto err;
1181 				} else {
1182 					/* check if the value is right */
1183 					strength = check_vpp_strength(deblock->value);
1184 					if (strength == INVALID_STRENGTH) {
1185 						vaStatus = VA_STATUS_ERROR_INVALID_VALUE;
1186 						goto err;
1187 					}
1188 					memcpy(&vpp_ctx->denoise_deblock_param,
1189 					       &vpp_strength[strength].denoise_deblock[res_set],
1190 					       sizeof(vpp_ctx->denoise_deblock_param));
1191 				}
1192 				break;
1193 
1194 			case VAProcFilterNoiseReduction:
1195 				denoise = (VAProcFilterParameterBuffer *)base;
1196 
1197 				if (combination_check &&
1198 				    vpp_chain_caps[res_set].denoise_enabled != FILTER_ENABLED) {
1199 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The denoise is DISABLE for %d format\n", res_set);
1200 					vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
1201 					goto err;
1202 				} else {
1203 					strength = check_vpp_strength(denoise->value);
1204 					if (strength == INVALID_STRENGTH) {
1205 						vaStatus = VA_STATUS_ERROR_INVALID_VALUE;
1206 						goto err;
1207 					}
1208 					memcpy(&vpp_ctx->denoise_deblock_param,
1209 					       &vpp_strength[strength].denoise_deblock[res_set],
1210 					       sizeof(vpp_ctx->denoise_deblock_param));
1211 				}
1212 				break;
1213 
1214 			case VAProcFilterSharpening:
1215 				sharpen = (VAProcFilterParameterBuffer *)base;
1216 
1217 				if (combination_check &&
1218 				    vpp_chain_caps[res_set].sharpen_enabled != FILTER_ENABLED) {
1219 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The sharpen is DISABLE for %d format\n", res_set);
1220 					vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
1221 					goto err;
1222 				} else {
1223 					strength = check_vpp_strength(sharpen->value);
1224 					if (strength == INVALID_STRENGTH) {
1225 						vaStatus = VA_STATUS_ERROR_INVALID_VALUE;
1226 						goto err;
1227 					}
1228 					memcpy(&vpp_ctx->sharpen_param,
1229 					      &vpp_strength[strength].sharpen[res_set],
1230 					       sizeof(vpp_ctx->sharpen_param));
1231 				}
1232 				break;
1233 
1234 			case VAProcFilterColorBalance:
1235 				balance = (VAProcFilterParameterBufferColorBalance *)base;
1236 
1237 				enabled_brightness = 0;
1238 				enabled_saturation = 0;
1239 
1240 				for (j = 0; j < buf->num_elements; ++j, ++balance) {
1241 					if (balance->attrib == VAProcColorBalanceAutoSaturation &&
1242 					    balance->value == MAX_VPP_AUTO_PARAM) {
1243 						enabled_saturation = 1;
1244 					} else if (balance->attrib == VAProcColorBalanceAutoBrightness &&
1245 						   balance->value == MAX_VPP_AUTO_PARAM) {
1246 						enabled_brightness = 1;
1247 					} else {
1248 						drv_debug_msg(VIDEO_DEBUG_ERROR, "The color_banlance do NOT support this attrib %d\n",
1249 							      balance->attrib);
1250 						vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1251 						goto err;
1252 					}
1253 				}
1254 
1255 				/* check filter chain */
1256 				if (combination_check &&
1257 				    vpp_chain_caps[res_set].color_balance_enabled != FILTER_ENABLED) {
1258 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The color_balance is DISABLE for %d format\n", res_set);
1259 					vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
1260 					goto err;
1261 				} else {
1262 					strength = MEDIUM_STRENGTH;
1263 					memcpy(&vpp_ctx->enhancer_param,
1264 					       &vpp_strength[strength].enhancer[res_set],
1265 					       sizeof(vpp_ctx->enhancer_param));
1266 					if (!enabled_saturation)
1267 						vpp_ctx->enhancer_param.chroma_amm = 0;
1268 					if (!enabled_brightness)
1269 						vpp_ctx->enhancer_param.luma_amm = 0;
1270 				}
1271 
1272 				break;
1273 
1274 			case VAProcFilterFrameRateConversion:
1275 				frc = (VAProcFilterParameterBufferFrameRateConversion *)base;
1276 
1277 				/* check frame rate */
1278 				ratio = frc->output_fps / (float)frc->input_fps;
1279 
1280 				if (!((ratio == 2 || ratio == 2.5 || ratio == 4) && frc->output_fps <= 60)) {
1281 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The FRC do NOT support the ration(%f) and fps(%d)\n",
1282 						      ratio, frc->output_fps);
1283 					vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1284 					goto err;
1285 				}
1286 
1287 				/* check the chain */
1288 				if (combination_check &&
1289 				    vpp_chain_caps[res_set].frc_enabled != FILTER_ENABLED) {
1290 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The FRC is DISABLE for %d format\n", res_set);
1291 					vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
1292 					goto err;
1293 				}
1294 
1295 				break;
1296 			default:
1297 				drv_debug_msg(VIDEO_DEBUG_ERROR, "Do NOT support the filter type %d\n", base->type);
1298 				vaStatus = VA_STATUS_ERROR_UNKNOWN;
1299 				goto err;
1300 			}
1301 		}
1302 	} else {
1303 		drv_debug_msg(VIDEO_DEBUG_ERROR, "no HW support\n");
1304 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
1305 		goto err;
1306 	}
1307 err:
1308 	return vaStatus;
1309 }
1310 
vsp_set_pipeline(context_VPP_p ctx)1311 static VAStatus vsp_set_pipeline(context_VPP_p ctx)
1312 {
1313 	VAStatus vaStatus = VA_STATUS_SUCCESS;
1314 	vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf;
1315 	struct VssProcPipelineParameterBuffer *cell_pipeline_param = (struct VssProcPipelineParameterBuffer *)cmdbuf->pipeline_param_p;
1316 	unsigned int i, j, filter_count, check_filter = 0;
1317 	VAProcFilterParameterBufferBase *cur_param;
1318 	enum VssProcFilterType tmp;
1319 	psb_driver_data_p driver_data = ctx->obj_context->driver_data;
1320 
1321 	/* set intermediate buffer */
1322 	cell_pipeline_param->intermediate_buffer_size = VSP_INTERMEDIATE_BUF_SIZE;
1323 	cell_pipeline_param->intermediate_buffer_base = wsbmBOOffsetHint(ctx->intermediate_buf->drm_buf);
1324 
1325 	/* init pipeline cmd */
1326 	for (i = 0; i < VssProcPipelineMaxNumFilters; ++i)
1327 		cell_pipeline_param->filter_pipeline[i] = -1;
1328 	cell_pipeline_param->num_filters = 0;
1329 
1330 	filter_count = 0;
1331 
1332 	/* store filter buffer object */
1333 	if (ctx->num_filters != 0) {
1334 		for (i = 0; i < ctx->num_filters; ++i)
1335 			ctx->filter_buf[i] = BUFFER(ctx->filters[i]);
1336 	} else {
1337 		goto finished;
1338 	}
1339 
1340 	/* loop the filter, set correct pipeline param for FW */
1341 	for (i = 0; i < ctx->num_filters; ++i) {
1342 		cur_param = (VAProcFilterParameterBufferBase *)ctx->filter_buf[i]->buffer_data;
1343 		switch (cur_param->type) {
1344 		case VAProcFilterNone:
1345 			goto finished;
1346 			break;
1347 		case VAProcFilterNoiseReduction:
1348 		case VAProcFilterDeblocking:
1349 			cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterDenoise;
1350 			check_filter++;
1351 			break;
1352 		case VAProcFilterSharpening:
1353 			cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterSharpening;
1354 			break;
1355 		case VAProcFilterColorBalance:
1356 			cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterColorEnhancement;
1357 			break;
1358 		case VAProcFilterFrameRateConversion:
1359 			cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterFrameRateConversion;
1360 			break;
1361 		default:
1362 			cell_pipeline_param->filter_pipeline[filter_count++] = -1;
1363 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
1364 			goto out;
1365 		}
1366 	}
1367 
1368 	/* Denoise and Deblock is alternative */
1369 	if (check_filter >= 2) {
1370 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Denoise and Deblock is alternative!\n");
1371 		cell_pipeline_param->filter_pipeline[filter_count++] = -1;
1372 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
1373 		goto out;
1374 	}
1375 
1376 finished:
1377 	cell_pipeline_param->num_filters = filter_count;
1378 
1379 	/* reorder */
1380 	for (i = 1; i < filter_count; ++i)
1381 		for (j = i; j > 0; --j)
1382 			if (cell_pipeline_param->filter_pipeline[j] < cell_pipeline_param->filter_pipeline[j - 1]) {
1383 				/* swap */
1384 				tmp = cell_pipeline_param->filter_pipeline[j];
1385 				cell_pipeline_param->filter_pipeline[j] = cell_pipeline_param->filter_pipeline[j - 1];
1386 				cell_pipeline_param->filter_pipeline[j - 1] = tmp;
1387 			}
1388 
1389 	vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VPP_ID, &cmdbuf->param_mem, VssProcPipelineParameterCommand,
1390 				  ctx->pipeline_param_offset, sizeof(struct VssProcPipelineParameterBuffer));
1391 out:
1392 	return vaStatus;
1393 }
1394 
vsp_set_filter_param(context_VPP_p ctx)1395 static VAStatus vsp_set_filter_param(context_VPP_p ctx)
1396 {
1397 	VAStatus vaStatus = VA_STATUS_SUCCESS;
1398 	vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf;
1399 	struct VssProcDenoiseParameterBuffer *cell_denoiser_param = (struct VssProcDenoiseParameterBuffer *)cmdbuf->denoise_param_p;
1400 	struct VssProcColorEnhancementParameterBuffer *cell_enhancer_param = (struct VssProcColorEnhancementParameterBuffer *)cmdbuf->enhancer_param_p;
1401 	struct VssProcSharpenParameterBuffer *cell_sharpen_param = (struct VssProcSharpenParameterBuffer *)cmdbuf->sharpen_param_p;
1402 	struct VssProcFrcParameterBuffer *cell_proc_frc_param = (struct VssProcFrcParameterBuffer *)cmdbuf->frc_param_p;
1403 	VAProcFilterParameterBufferBase *cur_param = NULL;
1404 	VAProcFilterParameterBufferFrameRateConversion *frc_param = NULL;
1405 	unsigned int i;
1406 	float ratio;
1407 
1408 	for (i = 0; i < ctx->num_filters; ++i) {
1409 		cur_param = (VAProcFilterParameterBufferBase *)ctx->filter_buf[i]->buffer_data;
1410 		switch (cur_param->type) {
1411 		case VAProcFilterDeblocking:
1412 			memcpy(cell_denoiser_param,
1413 			       &ctx->denoise_deblock_param,
1414 			       sizeof(ctx->denoise_deblock_param));
1415 			cell_denoiser_param->type = VssProcDeblock;
1416 
1417 			vsp_cmdbuf_insert_command(cmdbuf,
1418 						  CONTEXT_VPP_ID,
1419 						  &cmdbuf->param_mem,
1420 						  VssProcDenoiseParameterCommand,
1421 						  ctx->denoise_param_offset,
1422 						  sizeof(struct VssProcDenoiseParameterBuffer));
1423 			break;
1424 
1425 		case VAProcFilterNoiseReduction:
1426 			memcpy(cell_denoiser_param,
1427 			       &ctx->denoise_deblock_param,
1428 			       sizeof(ctx->denoise_deblock_param));
1429 			cell_denoiser_param->type = VssProcDegrain;
1430 
1431 			vsp_cmdbuf_insert_command(cmdbuf,
1432 						  CONTEXT_VPP_ID,
1433 						  &cmdbuf->param_mem,
1434 						  VssProcDenoiseParameterCommand,
1435 						  ctx->denoise_param_offset,
1436 						  sizeof(struct VssProcDenoiseParameterBuffer));
1437 			break;
1438 
1439 		case VAProcFilterSharpening:
1440 			memcpy(cell_sharpen_param,
1441 			       &ctx->sharpen_param,
1442 			       sizeof(ctx->sharpen_param));
1443 
1444 			vsp_cmdbuf_insert_command(cmdbuf,
1445 						  CONTEXT_VPP_ID,
1446 						  &cmdbuf->param_mem,
1447 						  VssProcSharpenParameterCommand,
1448 						  ctx->sharpen_param_offset,
1449 						  sizeof(struct VssProcSharpenParameterBuffer));
1450 			break;
1451 
1452 		case VAProcFilterColorBalance:
1453 			memcpy(cell_enhancer_param,
1454 			       &ctx->enhancer_param,
1455 			       sizeof(ctx->enhancer_param));
1456 
1457 			vsp_cmdbuf_insert_command(cmdbuf,
1458 						  CONTEXT_VPP_ID,
1459 						  &cmdbuf->param_mem,
1460 						  VssProcColorEnhancementParameterCommand,
1461 						  ctx->enhancer_param_offset,
1462 						  sizeof(struct VssProcColorEnhancementParameterBuffer));
1463 
1464 			break;
1465 
1466 		case VAProcFilterFrameRateConversion:
1467 			ctx->frc_buf = ctx->filter_buf[i];
1468 
1469 			frc_param = (VAProcFilterParameterBufferFrameRateConversion *)ctx->filter_buf[i]->buffer_data;
1470 			ratio = frc_param->output_fps / (float)frc_param->input_fps;
1471 
1472 			/* set the FRC quality */
1473 			/* cell_proc_frc_param->quality = VssFrcMediumQuality; */
1474 			cell_proc_frc_param->quality = VssFrcHighQuality;
1475 
1476 			/* check if the input fps is in the range of HW capability */
1477 			if (ratio == 2)
1478 				cell_proc_frc_param->conversion_rate = VssFrc2xConversionRate;
1479 			else if (ratio == 2.5)
1480 				cell_proc_frc_param->conversion_rate = VssFrc2_5xConversionRate;
1481 			else if (ratio == 4)
1482 				cell_proc_frc_param->conversion_rate = VssFrc4xConversionRate;
1483 			else if (ratio == 1.25)
1484 				cell_proc_frc_param->conversion_rate = VssFrc1_25xConversionRate;
1485 			else {
1486 				drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid frame rate conversion ratio %f \n", ratio);
1487 				vaStatus = VA_STATUS_ERROR_UNKNOWN;
1488 				goto out;
1489 			}
1490 
1491 			vsp_cmdbuf_insert_command(cmdbuf,
1492 						  CONTEXT_VPP_ID,
1493 						  &cmdbuf->param_mem,
1494 						  VssProcFrcParameterCommand,
1495 						  ctx->frc_param_offset,
1496 						  sizeof(struct VssProcFrcParameterBuffer));
1497 			break;
1498 		default:
1499 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
1500 			goto out;
1501 		}
1502 	}
1503 out:
1504 	return vaStatus;
1505 }
1506 
check_resolution(int width,int height)1507 static int check_resolution(int width, int height)
1508 {
1509 	int ret;
1510 	int image_area;
1511 
1512 	if (height < MIN_SUPPORTED_HEIGHT || height > MAX_SUPPORTED_HEIGHT)
1513 		return NOT_SUPPORTED_RESOLUTION;
1514 
1515 	image_area = height * width;
1516 
1517 	if (image_area <= QVGA_AREA)
1518 		ret = QCIF_TO_QVGA;
1519 	else if (image_area <= VGA_AREA)
1520 		ret = QVGA_TO_VGA;
1521 	else if (image_area <= SD_AREA)
1522 		ret = VGA_TO_SD;
1523 	else if (image_area <= HD720P_AREA)
1524 		ret = SD_TO_720P;
1525 	else if (image_area <= HD1080P_AREA)
1526 		ret = HD720P_TO_1080P;
1527 	else
1528 		ret = NOT_SUPPORTED_RESOLUTION;
1529 
1530 	return ret;
1531 }
1532 
1533 /*
1534  * The strength area is:
1535  *
1536  * 0______33______66______100
1537  *   LOW     MED     HIGH
1538  *
1539  * MIN=0; MAX=100; STEP=33
1540  */
check_vpp_strength(int value)1541 static int check_vpp_strength(int value)
1542 {
1543 	if (value < MIN_VPP_PARAM || value > MAX_VPP_PARAM)
1544 		return INVALID_STRENGTH;
1545 
1546 	if (value >= MIN_VPP_PARAM &&
1547 	    value < MIN_VPP_PARAM + STEP_VPP_PARAM)
1548 		return LOW_STRENGTH;
1549 	else if (value >= MIN_VPP_PARAM + STEP_VPP_PARAM &&
1550 		 value < MIN_VPP_PARAM + 2 * STEP_VPP_PARAM)
1551 		return MEDIUM_STRENGTH;
1552 	else
1553 		return HIGH_STRENGTH;
1554 }
1555