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