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 		free(ctx);
367 
368 	return vaStatus;
369 }
370 
vsp_VPP_DestroyContext(object_context_p obj_context)371 static void vsp_VPP_DestroyContext(
372 	object_context_p obj_context)
373 {
374 	INIT_CONTEXT_VPP;
375 
376 	if (ctx->intermediate_buf) {
377 		psb_buffer_destroy(ctx->intermediate_buf);
378 
379 		free(ctx->intermediate_buf);
380 		ctx->intermediate_buf = NULL;
381 	}
382 
383 	if (ctx->filters) {
384 		free(ctx->filters);
385 		ctx->num_filters = 0;
386 	}
387 
388 	free(obj_context->format_data);
389 	obj_context->format_data = NULL;
390 }
391 
vsp__VPP_process_pipeline_param(context_VPP_p ctx,object_context_p obj_context,object_buffer_p obj_buffer)392 static VAStatus vsp__VPP_process_pipeline_param(context_VPP_p ctx, object_context_p obj_context, object_buffer_p obj_buffer)
393 {
394 	VAStatus vaStatus = VA_STATUS_SUCCESS;
395 	vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf;
396 	unsigned int i = 0;
397 	VAProcPipelineParameterBuffer *pipeline_param = (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data;
398 	struct VssProcPictureParameterBuffer *cell_proc_picture_param = (struct VssProcPictureParameterBuffer *)cmdbuf->pic_param_p;
399 	struct VssProcPictureParameterBuffer *cell_end_param = (struct VssProcPictureParameterBuffer *)cmdbuf->end_param_p;
400 	VAProcFilterParameterBufferFrameRateConversion *frc_param;
401 	object_surface_p input_surface = NULL;
402 	object_surface_p cur_output_surf = NULL;
403 	unsigned int rotation_angle = 0, vsp_rotation_angle = 0;
404 	unsigned int tiled = 0, width = 0, height = 0, stride = 0;
405 	unsigned char *src_addr, *dest_addr;
406 	struct psb_surface_s *output_surface;
407 	psb_surface_share_info_p input_share_info = NULL;
408 	psb_surface_share_info_p output_share_info = NULL;
409  	enum vsp_format format;
410 
411 
412 	psb_driver_data_p driver_data = obj_context->driver_data;
413 
414 	if (pipeline_param->surface_region != NULL) {
415 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Cann't scale\n");
416 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
417 		goto out;
418 	}
419 
420 	if (pipeline_param->output_region != NULL) {
421 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Cann't scale\n");
422 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
423 		goto out;
424 	}
425 
426 	if (pipeline_param->output_background_color != 0) {
427 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Cann't support background color here\n");
428 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
429 		goto out;
430 	}
431 
432 	if (pipeline_param->filters == NULL) {
433 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filter setting filters = %p\n", pipeline_param->filters);
434 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
435 		goto out;
436 	}
437 
438 #if 0
439 	/* for pass filter */
440 	if (pipeline_param->num_filters == 0 || pipeline_param->num_filters > VssProcPipelineMaxNumFilters) {
441 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filter number = %d\n", pipeline_param->num_filters);
442 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
443 		goto out;
444 	}
445 #endif
446 
447 	if (pipeline_param->forward_references == NULL) {
448 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid forward_refereces %p setting\n", pipeline_param->forward_references);
449 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
450 		goto out;
451 	}
452 
453 	/* should we check it? since the begining it's not VSP_FORWARD_REF_NUM */
454 	if (pipeline_param->num_forward_references != VSP_FORWARD_REF_NUM) {
455 		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);
456 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
457 		goto out;
458 	}
459 
460 	/* first picture, need to setup the VSP context */
461 	if (ctx->obj_context->frame_count == 0)
462 		vsp_cmdbuf_vpp_context(cmdbuf, VssGenInitializeContext, CONTEXT_VPP_ID, VSP_APP_ID_FRC_VPP);
463 
464 	/* get the input surface */
465 	if (!(pipeline_param->pipeline_flags & VA_PIPELINE_FLAG_END)) {
466 		input_surface = SURFACE(pipeline_param->surface);
467 		if (input_surface == NULL) {
468 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid input surface %x\n", pipeline_param->surface);
469 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
470 			goto out;
471 		}
472 	} else {
473 		input_surface = NULL;
474 	}
475 
476 	/* if it is the first pipeline command */
477 	if (pipeline_param->num_filters != ctx->num_filters || pipeline_param->num_filters == 0) {
478 		if (ctx->num_filters != 0) {
479 			drv_debug_msg(VIDEO_DEBUG_ERROR, "can not reset pipeline in the mid of post-processing or without create a new context\n");
480 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
481 			goto out;
482 		} else {
483 			/* save filters */
484 			ctx->num_filters = pipeline_param->num_filters;
485 			if (ctx->num_filters == 0) {
486 				ctx->filters = NULL;
487 			} else {
488 				ctx->filters = (VABufferID *) calloc(ctx->num_filters, sizeof(*ctx->filters));
489 				if (ctx->filters == NULL) {
490 					drv_debug_msg(VIDEO_DEBUG_ERROR, "can not reset pipeline in the mid of post-processing or without create a new context\n");
491 					vaStatus = VA_STATUS_ERROR_UNKNOWN;
492 					goto out;
493 				}
494 				memcpy(ctx->filters, pipeline_param->filters, ctx->num_filters * sizeof(*ctx->filters));
495 			}
496 
497 			/* set pipeline command to FW */
498 			vaStatus = vsp_set_pipeline(ctx);
499 			if (vaStatus) {
500 				drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to set pipeline\n");
501 				goto out;
502 			}
503 
504 			/* set filter parameter to FW, record frc parameter buffer */
505 			vaStatus = vsp_set_filter_param(ctx);
506 			if (vaStatus) {
507 				drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to set filter parameter\n");
508 				goto out;
509 			}
510 		}
511 	} else {
512 		/* else ignore pipeline/filter setting  */
513 #if 0
514 		/* FIXME: we can save these check for PnP */
515 		for (i = 0; i < pipeline_param->num_filters; i++) {
516 			if (pipeline_param->filters[i] != ctx->filters[i]) {
517 				drv_debug_msg(VIDEO_DEBUG_ERROR, "can not reset pipeline in the mid of post-processing or without create a new context\n");
518 				vaStatus = VA_STATUS_ERROR_UNKNOWN;
519 				goto out;
520 			}
521 		}
522 #endif
523 	}
524 
525 	/* fill picture command to FW */
526 	if (ctx->frc_buf != NULL)
527 		frc_param = (VAProcFilterParameterBufferFrameRateConversion *)ctx->frc_buf->buffer_data;
528 	else
529 		frc_param = NULL;
530 
531 	/* end picture command */
532 	if (pipeline_param->pipeline_flags & VA_PIPELINE_FLAG_END) {
533 		cell_end_param->num_input_pictures = 0;
534 		cell_end_param->num_output_pictures = 0;
535 		vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VPP_ID, &cmdbuf->param_mem, VssProcPictureCommand,
536 					  ctx->end_param_offset, sizeof(struct VssProcPictureParameterBuffer));
537 		/* Destory the VSP context */
538 		vsp_cmdbuf_vpp_context(cmdbuf, VssGenDestroyContext, CONTEXT_VPP_ID, 0);
539 		goto out;
540 	}
541 
542 #ifdef PSBVIDEO_VPP_TILING
543 	/* get the tiling flag*/
544 	tiled = GET_SURFACE_INFO_tiling(input_surface->psb_surface);
545 #endif
546 
547 	/* get the surface format info  */
548 	switch (input_surface->psb_surface->extra_info[8]) {
549 		case VA_FOURCC_YV12:
550 			format = VSP_YV12;
551 			break;
552 		case VA_FOURCC_NV12:
553 			format = VSP_NV12;
554 			break;
555 		default:
556 			vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
557 			drv_debug_msg(VIDEO_DEBUG_ERROR, "Only support NV12 and YV12 format!\n");
558 			goto out;
559 	}
560 
561 	/*  According to VIED's design, the width must be multiple of 16 */
562 	width = ALIGN_TO_16(input_surface->width);
563 	if (width > input_surface->psb_surface->stride)
564 		width = input_surface->psb_surface->stride;
565 
566 	/* get the input share info */
567 	input_share_info = input_surface->share_info;
568 	drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s The input surface %p share info %p\n", __func__, input_surface,input_surface->share_info);
569 
570 	/* Setup input surface */
571 	cell_proc_picture_param->num_input_pictures  = 1;
572 	cell_proc_picture_param->input_picture[0].surface_id = pipeline_param->surface;
573 	vsp_cmdbuf_reloc_pic_param(&(cell_proc_picture_param->input_picture[0].base), ctx->pic_param_offset, &(input_surface->psb_surface->buf),
574 				   cmdbuf->param_mem_loc, cell_proc_picture_param);
575 	cell_proc_picture_param->input_picture[0].height = input_surface->height;
576 	cell_proc_picture_param->input_picture[0].width = width;
577 	cell_proc_picture_param->input_picture[0].irq = 0;
578 	cell_proc_picture_param->input_picture[0].stride = input_surface->psb_surface->stride;
579 	cell_proc_picture_param->input_picture[0].format = format;
580 	cell_proc_picture_param->input_picture[0].tiled = tiled;
581 	cell_proc_picture_param->input_picture[0].rot_angle = 0;
582 
583 	/* Setup output surfaces */
584 	if (frc_param == NULL)
585 		cell_proc_picture_param->num_output_pictures = 1;
586 	else
587 		cell_proc_picture_param->num_output_pictures = frc_param->num_output_frames + 1;
588 
589 	for (i = 0; i < cell_proc_picture_param->num_output_pictures; ++i) {
590 		if (i == 0) {
591 			cur_output_surf = ctx->obj_context->current_render_target;
592 
593 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
594 			/* The rotation info is saved in the first frame */
595 			rotation_angle = GET_SURFACE_INFO_rotate(cur_output_surf->psb_surface);
596 			switch (rotation_angle) {
597 				case VA_ROTATION_90:
598 					vsp_rotation_angle = VSP_ROTATION_90;
599 					break;
600 				case VA_ROTATION_180:
601 					vsp_rotation_angle = VSP_ROTATION_180;
602 					break;
603 				case VA_ROTATION_270:
604 					vsp_rotation_angle = VSP_ROTATION_270;
605 					break;
606 				default:
607 					vsp_rotation_angle = VSP_ROTATION_NONE;
608 			}
609 #endif
610 		} else {
611 			if (frc_param == NULL) {
612 				drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid output surface numbers %x\n",
613 					      cell_proc_picture_param->num_output_pictures);
614 				vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
615 				goto out;
616 			}
617 
618 			cur_output_surf = SURFACE(frc_param->output_frames[i-1]);
619 			if (cur_output_surf == NULL) {
620 				drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid input surface %x\n", frc_param->output_frames[i-1]);
621 				vaStatus = VA_STATUS_ERROR_UNKNOWN;
622 				goto out;
623 			}
624 
625 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
626 			/* VPP rotation is just for 1080P */
627 			if (tiled && rotation_angle != VA_ROTATION_NONE) {
628 				if (VA_STATUS_SUCCESS != psb_CreateRotateSurface(obj_context, cur_output_surf, rotation_angle)) {
629 					drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to alloc rotation surface!\n");
630 					vaStatus = VA_STATUS_ERROR_UNKNOWN;
631 					goto out;
632 				}
633 			}
634 #endif
635 		}
636 
637 		if (tiled && rotation_angle != VA_ROTATION_NONE) {
638 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
639 			/* For 90d and 270d, we need to alloc rotation buff and
640 			 * copy the 0d data from input to output
641 			 */
642 			psb_buffer_map(&(input_surface->psb_surface->buf), &src_addr);
643 			psb_buffer_map(&(cur_output_surf->psb_surface->buf), &dest_addr);
644 			memcpy(dest_addr, src_addr, cur_output_surf->psb_surface->size);
645 			psb_buffer_unmap(&(cur_output_surf->psb_surface->buf));
646 			psb_buffer_unmap(&(input_surface->psb_surface->buf));
647 
648 			output_surface = cur_output_surf->out_loop_surface;
649 
650 			/*  According to VIED's design, the width must be multiple of 16 */
651 			width = ALIGN_TO_16(cur_output_surf->height_origin);
652 			if (width > cur_output_surf->out_loop_surface->stride)
653 				width = cur_output_surf->out_loop_surface->stride;
654 			height = cur_output_surf->width;
655 			stride = cur_output_surf->out_loop_surface->stride;
656 #endif
657 		} else {
658 			output_surface = cur_output_surf->psb_surface;
659 
660 			/*  According to VIED's design, the width must be multiple of 16 */
661 			width = ALIGN_TO_16(cur_output_surf->width);
662 			if (width > cur_output_surf->psb_surface->stride)
663 				width = cur_output_surf->psb_surface->stride;
664 			height = cur_output_surf->height;
665 			stride = cur_output_surf->psb_surface->stride;
666 
667 			/* Check the rotate bit */
668 			if (pipeline_param->rotation_state == VA_ROTATION_90)
669 				vsp_rotation_angle = VSP_ROTATION_90;
670 			else if (pipeline_param->rotation_state == VA_ROTATION_180)
671 				vsp_rotation_angle = VSP_ROTATION_180;
672 			else if (pipeline_param->rotation_state == VA_ROTATION_270)
673 				vsp_rotation_angle = VSP_ROTATION_270;
674 			else
675 				vsp_rotation_angle = VSP_ROTATION_NONE;
676 		}
677 
678 		cell_proc_picture_param->output_picture[i].surface_id = wsbmKBufHandle(wsbmKBuf(output_surface->buf.drm_buf));
679 
680 		vsp_cmdbuf_reloc_pic_param(&(cell_proc_picture_param->output_picture[i].base),
681 					   ctx->pic_param_offset, &(output_surface->buf),
682 					   cmdbuf->param_mem_loc, cell_proc_picture_param);
683 		cell_proc_picture_param->output_picture[i].height = height;
684 		cell_proc_picture_param->output_picture[i].width = width;
685 		cell_proc_picture_param->output_picture[i].stride = stride;
686 		cell_proc_picture_param->output_picture[i].irq = 1;
687 		cell_proc_picture_param->output_picture[i].format = format;
688 		cell_proc_picture_param->output_picture[i].rot_angle = vsp_rotation_angle;
689 		cell_proc_picture_param->output_picture[i].tiled = tiled;
690 
691 		/* copy the input share info to output */
692 		output_share_info = cur_output_surf->share_info;
693 		if (input_share_info != NULL && output_share_info != NULL) {
694             output_share_info->native_window = input_share_info->native_window;
695             output_share_info->force_output_method = input_share_info->force_output_method;
696             output_share_info->surface_protected = input_share_info->surface_protected;
697             output_share_info->bob_deinterlace = input_share_info->bob_deinterlace;
698 
699             output_share_info->crop_width = input_share_info->crop_width;
700             output_share_info->crop_height = input_share_info->crop_height;
701             output_share_info->coded_width = input_share_info->coded_width;
702             output_share_info->coded_height = input_share_info->coded_height;
703 			drv_debug_msg(VIDEO_DEBUG_GENERAL, "The input/output wxh %dx%d\n",input_share_info->width,input_share_info->height);
704 		} else {
705 			drv_debug_msg(VIDEO_DEBUG_WARNING, "The input/output share_info is NULL!!\n");
706 		}
707 	}
708 
709 	vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VPP_ID, &cmdbuf->param_mem, VssProcPictureCommand,
710 				  ctx->pic_param_offset, sizeof(struct VssProcPictureParameterBuffer));
711 
712 	vsp_cmdbuf_fence_pic_param(cmdbuf, wsbmKBufHandle(wsbmKBuf(cmdbuf->param_mem.drm_buf)));
713 
714 #if 0
715 	/* handle reference frames, ignore backward reference */
716 	for (i = 0; i < pipeline_param->num_forward_references; ++i) {
717 		cur_output_surf = SURFACE(pipeline_param->forward_references[i]);
718 		if (cur_output_surf == NULL)
719 			continue;
720 		if (vsp_cmdbuf_buffer_ref(cmdbuf, &cur_output_surf->psb_surface->buf) < 0) {
721 			drv_debug_msg(VIDEO_DEBUG_ERROR, "vsp_cmdbuf_buffer_ref() failed\n");
722 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
723 			goto out;
724 		}
725 	}
726 #endif
727 out:
728 	free(pipeline_param);
729 	obj_buffer->buffer_data = NULL;
730 	obj_buffer->size = 0;
731 
732 	return vaStatus;
733 }
734 
vsp_VPP_RenderPicture(object_context_p obj_context,object_buffer_p * buffers,int num_buffers)735 static VAStatus vsp_VPP_RenderPicture(
736 	object_context_p obj_context,
737 	object_buffer_p *buffers,
738 	int num_buffers)
739 {
740 	int i;
741 	INIT_CONTEXT_VPP;
742 	VAProcPipelineParameterBuffer *pipeline_param = NULL;
743 	VAStatus vaStatus = VA_STATUS_SUCCESS;
744 
745 	for (i = 0; i < num_buffers; i++) {
746 		object_buffer_p obj_buffer = buffers[i];
747 		pipeline_param = (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data;
748 
749 		switch (obj_buffer->type) {
750 		case VAProcPipelineParameterBufferType:
751 			if (!pipeline_param->num_filters && pipeline_param->blend_state)
752 				/* For Security Composer */
753 				vaStatus = vsp_compose_process_pipeline_param(ctx, obj_context, obj_buffer);
754 			else
755 				/* For VPP/FRC */
756 				vaStatus = vsp__VPP_process_pipeline_param(ctx, obj_context, obj_buffer);
757 			DEBUG_FAILURE;
758 			break;
759 		default:
760 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
761 			DEBUG_FAILURE;
762 		}
763 		if (vaStatus != VA_STATUS_SUCCESS) {
764 			break;
765 		}
766 	}
767 
768 	return vaStatus;
769 }
770 
vsp_VPP_BeginPicture(object_context_p obj_context)771 static VAStatus vsp_VPP_BeginPicture(
772 	object_context_p obj_context)
773 {
774 	int ret;
775 	VAStatus vaStatus = VA_STATUS_SUCCESS;
776 	INIT_CONTEXT_VPP;
777 	vsp_cmdbuf_p cmdbuf;
778 
779 	/* Initialise the command buffer */
780 	ret = vsp_context_get_next_cmdbuf(ctx->obj_context);
781 	if (ret) {
782 		drv_debug_msg(VIDEO_DEBUG_GENERAL, "get next cmdbuf fail\n");
783 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
784 		return vaStatus;
785 	}
786 
787 	cmdbuf = obj_context->vsp_cmdbuf;
788 
789 	/* map param mem */
790 	vaStatus = psb_buffer_map(&cmdbuf->param_mem, &cmdbuf->param_mem_p);
791 	if (vaStatus) {
792 		return vaStatus;
793 	}
794 
795 	cmdbuf->pic_param_p = cmdbuf->param_mem_p + ctx->pic_param_offset;
796 	cmdbuf->end_param_p = cmdbuf->param_mem_p + ctx->end_param_offset;
797 	cmdbuf->pipeline_param_p = cmdbuf->param_mem_p + ctx->pipeline_param_offset;
798 	cmdbuf->denoise_param_p = cmdbuf->param_mem_p + ctx->denoise_param_offset;
799 	cmdbuf->enhancer_param_p = cmdbuf->param_mem_p + ctx->enhancer_param_offset;
800 	cmdbuf->sharpen_param_p = cmdbuf->param_mem_p + ctx->sharpen_param_offset;
801 	cmdbuf->frc_param_p = cmdbuf->param_mem_p + ctx->frc_param_offset;
802 	cmdbuf->compose_param_p = cmdbuf->param_mem_p + ctx->compose_param_offset;
803 
804 	return VA_STATUS_SUCCESS;
805 }
806 
vsp_VPP_EndPicture(object_context_p obj_context)807 static VAStatus vsp_VPP_EndPicture(
808 	object_context_p obj_context)
809 {
810 	INIT_CONTEXT_VPP;
811 	psb_driver_data_p driver_data = obj_context->driver_data;
812 	vsp_cmdbuf_p cmdbuf = obj_context->vsp_cmdbuf;
813 
814 	if(cmdbuf->param_mem_p != NULL) {
815 		psb_buffer_unmap(&cmdbuf->param_mem);
816 		cmdbuf->param_mem_p = NULL;
817 		cmdbuf->pic_param_p = NULL;
818 		cmdbuf->end_param_p = NULL;
819 		cmdbuf->pipeline_param_p = NULL;
820 		cmdbuf->denoise_param_p = NULL;
821 		cmdbuf->enhancer_param_p = NULL;
822 		cmdbuf->sharpen_param_p = NULL;
823 		cmdbuf->frc_param_p = NULL;
824 		cmdbuf->compose_param_p = NULL;
825 	}
826 
827 	if (vsp_context_flush_cmdbuf(ctx->obj_context)) {
828 		drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_VPP: flush deblock cmdbuf error\n");
829 		return VA_STATUS_ERROR_UNKNOWN;
830 	}
831 
832 	return VA_STATUS_SUCCESS;
833 }
834 
835 struct format_vtable_s vsp_VPP_vtable = {
836 queryConfigAttributes:
837 vsp_VPP_QueryConfigAttributes,
838 validateConfig:
839 vsp_VPP_ValidateConfig,
840 createContext:
841 vsp_VPP_CreateContext,
842 destroyContext:
843 vsp_VPP_DestroyContext,
844 beginPicture:
845 vsp_VPP_BeginPicture,
846 renderPicture:
847 vsp_VPP_RenderPicture,
848 endPicture:
849 vsp_VPP_EndPicture
850 };
851 
vsp_QueryVideoProcFilters(VADriverContextP ctx,VAContextID context,VAProcFilterType * filters,unsigned int * num_filters)852 VAStatus vsp_QueryVideoProcFilters(
853 	VADriverContextP    ctx,
854 	VAContextID         context,
855 	VAProcFilterType   *filters,
856 	unsigned int       *num_filters
857 	)
858 {
859 	INIT_DRIVER_DATA;
860 	VAStatus vaStatus = VA_STATUS_SUCCESS;
861 	object_context_p obj_context;
862 	object_config_p obj_config;
863 	VAEntrypoint tmp;
864 	int count;
865 
866 	/* check if ctx is right */
867 	obj_context = CONTEXT(context);
868 	if (NULL == obj_context) {
869 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
870 		vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
871 		goto err;
872 	}
873 
874 	obj_config = CONFIG(obj_context->config_id);
875 	if (NULL == obj_config) {
876 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
877 		vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
878 		goto err;
879 	}
880 
881 	tmp = obj_config->entrypoint;
882 	if (tmp != VAEntrypointVideoProc) {
883 		drv_debug_msg(VIDEO_DEBUG_ERROR, "current entrypoint is %d, not VAEntrypointVideoProc\n", tmp);
884 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
885 		goto err;
886 	}
887 
888 	/* check if filters and num_filters is valid */
889 	if (NULL == num_filters || NULL == filters) {
890 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filters, filters);
891 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
892 		goto err;
893 	}
894 
895 	/* check if the filter array size is valid */
896 	if (*num_filters < VSP_SUPPORTED_FILTERS_NUM) {
897 		drv_debug_msg(VIDEO_DEBUG_ERROR, "The filters array size(%d) is NOT valid! Supported filters num is %d\n",
898 				*num_filters, VSP_SUPPORTED_FILTERS_NUM);
899 		vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
900 		*num_filters = VSP_SUPPORTED_FILTERS_NUM;
901 		goto err;
902 	}
903 
904 	/* check if current HW support Video proc */
905 	if (IS_MRFL(driver_data)) {
906 		count = 0;
907 		filters[count++] = VAProcFilterDeblocking;
908 		filters[count++] = VAProcFilterNoiseReduction;
909 		filters[count++] = VAProcFilterSharpening;
910 		filters[count++] = VAProcFilterColorBalance;
911 		filters[count++] = VAProcFilterFrameRateConversion;
912 		*num_filters = count;
913 	} else {
914 		*num_filters = 0;
915 	}
916 err:
917 	return vaStatus;
918 }
919 
vsp_QueryVideoProcFilterCaps(VADriverContextP ctx,VAContextID context,VAProcFilterType type,void * filter_caps,unsigned int * num_filter_caps)920 VAStatus vsp_QueryVideoProcFilterCaps(
921 	VADriverContextP    ctx,
922 	VAContextID         context,
923 	VAProcFilterType    type,
924 	void               *filter_caps,
925 	unsigned int       *num_filter_caps
926 	)
927 {
928 	INIT_DRIVER_DATA;
929 	VAStatus vaStatus = VA_STATUS_SUCCESS;
930 	object_context_p obj_context;
931 	object_config_p obj_config;
932 	VAEntrypoint tmp;
933 	VAProcFilterCap *denoise_cap, *deblock_cap;
934 	VAProcFilterCap *sharpen_cap;
935 	VAProcFilterCapColorBalance *color_balance_cap;
936 	VAProcFilterCap *frc_cap;
937 
938 	/* check if context is right */
939 	obj_context = CONTEXT(context);
940 	if (NULL == obj_context) {
941 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
942 		vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
943 		goto err;
944 	}
945 
946 	obj_config = CONFIG(obj_context->config_id);
947 	if (NULL == obj_config) {
948 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
949 		vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
950 		goto err;
951 	}
952 
953 	/* check if filter_caps and num_filter_caps is right */
954 	if (NULL == num_filter_caps || NULL == filter_caps){
955 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filter_caps, filter_caps);
956 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
957 		goto err;
958 	}
959 
960 	if (*num_filter_caps < 1) {
961 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters == %d (> 1)\n", *num_filter_caps);
962 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
963 		goto err;
964 	}
965 
966 	/* check if curent HW support and return corresponding caps */
967 	if (IS_MRFL(driver_data)) {
968 		/* FIXME: we should use a constant table to return caps */
969 		switch (type) {
970 		case VAProcFilterNoiseReduction:
971 			denoise_cap = filter_caps;
972 			denoise_cap->range.min_value = MIN_VPP_PARAM;
973 			denoise_cap->range.max_value = MAX_VPP_PARAM;
974 			denoise_cap->range.default_value = MIN_VPP_PARAM;
975 			denoise_cap->range.step = STEP_VPP_PARAM;
976 			*num_filter_caps = 1;
977 			break;
978 		case VAProcFilterDeblocking:
979 			deblock_cap = filter_caps;
980 			deblock_cap->range.min_value = MIN_VPP_PARAM;
981 			deblock_cap->range.max_value = MAX_VPP_PARAM;
982 			deblock_cap->range.default_value = MIN_VPP_PARAM;
983 			deblock_cap->range.step = STEP_VPP_PARAM;
984 			*num_filter_caps = 1;
985 			break;
986 
987 		case VAProcFilterSharpening:
988 			sharpen_cap = filter_caps;
989 			sharpen_cap->range.min_value = MIN_VPP_PARAM;
990 			sharpen_cap->range.max_value = MAX_VPP_PARAM;
991 			sharpen_cap->range.default_value = MIN_VPP_PARAM;
992 			sharpen_cap->range.step = STEP_VPP_PARAM;
993 			*num_filter_caps = 1;
994 			break;
995 
996 		case VAProcFilterColorBalance:
997 			if (*num_filter_caps < VSP_COLOR_ENHANCE_FEATURES) {
998 				drv_debug_msg(VIDEO_DEBUG_ERROR, "filter cap num is should big than %d(%d)\n",
999 					      VSP_COLOR_ENHANCE_FEATURES, *num_filter_caps);
1000 				vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1001 				*num_filter_caps = VSP_COLOR_ENHANCE_FEATURES;
1002 				goto err;
1003 			}
1004 			color_balance_cap = filter_caps;
1005 			color_balance_cap->type = VAProcColorBalanceAutoSaturation;
1006 			color_balance_cap->range.min_value = MIN_VPP_AUTO_PARAM;
1007 			color_balance_cap->range.max_value = MAX_VPP_AUTO_PARAM;
1008 			color_balance_cap->range.default_value = MIN_VPP_AUTO_PARAM;
1009 			color_balance_cap->range.step = STEP_VPP_AUTO_PARAM;
1010 
1011 			color_balance_cap++;
1012 			color_balance_cap->type = VAProcColorBalanceAutoBrightness;
1013 			color_balance_cap->range.min_value = MIN_VPP_AUTO_PARAM;
1014 			color_balance_cap->range.max_value = MAX_VPP_AUTO_PARAM;
1015 			color_balance_cap->range.default_value = MIN_VPP_AUTO_PARAM;
1016 			color_balance_cap->range.step = STEP_VPP_AUTO_PARAM;
1017 
1018 			*num_filter_caps = 2;
1019 			break;
1020 
1021 		case VAProcFilterFrameRateConversion:
1022 			frc_cap = filter_caps;
1023 			frc_cap->range.min_value = 2;
1024 			frc_cap->range.max_value = 4;
1025 			frc_cap->range.default_value = 2;
1026 			/* FIXME: it's a set, step is helpless */
1027 			frc_cap->range.step = 0.5;
1028 			*num_filter_caps = 1;
1029 			break;
1030 
1031 		default:
1032 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide filter type %d\n", type);
1033 			vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1034 			*num_filter_caps = 0;
1035 			goto err;
1036 		}
1037 	} else {
1038 		*num_filter_caps = 0;
1039 	}
1040 
1041 err:
1042 	return vaStatus;
1043 }
1044 
vsp_QueryVideoProcPipelineCaps(VADriverContextP ctx,VAContextID context,VABufferID * filters,unsigned int num_filters,VAProcPipelineCaps * pipeline_caps)1045 VAStatus vsp_QueryVideoProcPipelineCaps(
1046 	VADriverContextP    ctx,
1047 	VAContextID         context,
1048 	VABufferID         *filters,
1049 	unsigned int        num_filters,
1050 	VAProcPipelineCaps *pipeline_caps
1051     )
1052 {
1053 	INIT_DRIVER_DATA;
1054 	VAStatus vaStatus = VA_STATUS_SUCCESS;
1055 	object_context_p obj_context;
1056 	object_config_p obj_config;
1057 	VAEntrypoint tmp;
1058 	unsigned int i, j;
1059 	VAProcFilterParameterBuffer *deblock, *denoise, *sharpen;
1060 	VAProcFilterParameterBufferFrameRateConversion *frc;
1061 	VAProcFilterParameterBufferColorBalance *balance;
1062 	VAProcFilterParameterBufferBase *base;
1063 	object_buffer_p buf;
1064 	uint32_t enabled_brightness, enabled_saturation;
1065 	float ratio;
1066 	int res_set;
1067 	int strength;
1068 	context_VPP_p vpp_ctx;
1069 	int combination_check;
1070 
1071 	/* check if ctx is right */
1072 	obj_context = CONTEXT(context);
1073 	if (NULL == obj_context) {
1074 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
1075 		vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
1076 		goto err;
1077 	}
1078 
1079 	vpp_ctx = (context_VPP_p) obj_context->format_data;
1080 
1081 	obj_config = CONFIG(obj_context->config_id);
1082 	if (NULL == obj_config) {
1083 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
1084 		vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
1085 		goto err;
1086 	}
1087 
1088 	/* Don't check the filter number.
1089 	 * According to VIED's design, without any filter, HW will just copy input data
1090 	 */
1091 #if 0
1092 	if (num_filters == 0) {
1093 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_filters %d\n", num_filters);
1094 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1095 		goto err;
1096 	}
1097 #endif
1098 	if (NULL == filters || pipeline_caps == NULL) {
1099 		drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filters %p or pipeline_caps %p\n", filters, pipeline_caps);
1100 		vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1101 		goto err;
1102 	}
1103 
1104 	/* base on HW capability check the filters and return pipeline caps */
1105 	if (IS_MRFL(driver_data)) {
1106 		pipeline_caps->pipeline_flags = 0;
1107 		pipeline_caps->filter_flags = 0;
1108 		pipeline_caps->num_forward_references = VSP_FORWARD_REF_NUM;
1109 		pipeline_caps->num_backward_references = 0;
1110 
1111 		/* check the input color standard */
1112 		if (pipeline_caps->input_color_standards == NULL){
1113 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid input color standard array!\n");
1114 			vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1115 			goto err;
1116 		}
1117 		if (pipeline_caps->num_input_color_standards < COLOR_STANDARDS_NUM) {
1118 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_input_color_standards %d\n", pipeline_caps->num_input_color_standards);
1119 			vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1120 			pipeline_caps->num_input_color_standards = COLOR_STANDARDS_NUM;
1121 			goto err;
1122 		}
1123 		pipeline_caps->input_color_standards[0] = VAProcColorStandardNone;
1124 		pipeline_caps->num_input_color_standards = COLOR_STANDARDS_NUM;
1125 
1126 		/* check the output color standard */
1127 		if (pipeline_caps->output_color_standards == NULL){
1128 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid output color standard array!\n");
1129 			vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1130 			goto err;
1131 		}
1132 		if (pipeline_caps->num_output_color_standards < COLOR_STANDARDS_NUM) {
1133 			drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_output_color_standards %d\n", pipeline_caps->num_output_color_standards);
1134 			vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1135 			pipeline_caps->num_output_color_standards = COLOR_STANDARDS_NUM;
1136 			goto err;
1137 		}
1138 		pipeline_caps->output_color_standards[0] = VAProcColorStandardNone;
1139 		pipeline_caps->num_output_color_standards = COLOR_STANDARDS_NUM;
1140 
1141 		/* check the resolution */
1142 		res_set = check_resolution(obj_context->picture_width,
1143 					   obj_context->picture_height);
1144 		if (res_set == NOT_SUPPORTED_RESOLUTION) {
1145 			vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
1146 			goto err;
1147 		}
1148 
1149 		/* Blend type */
1150 		pipeline_caps->blend_flags = VA_BLEND_PREMULTIPLIED_ALPHA;
1151 
1152 		if (getenv("VSP_PIPELINE_CHECK") != NULL)
1153 			combination_check = 1;
1154 		else
1155 			combination_check = 0;
1156 
1157 		/* FIXME: should check filter value settings here */
1158 		for (i = 0; i < num_filters; ++i) {
1159 			/* find buffer */
1160 			buf = BUFFER(*(filters + i));
1161 			if (!buf) {
1162 				vaStatus = VA_STATUS_ERROR_UNKNOWN;
1163 				goto err;
1164 			}
1165 
1166 			base = (VAProcFilterParameterBufferBase *)buf->buffer_data;
1167 			/* check filter buffer setting */
1168 			switch (base->type) {
1169 			case VAProcFilterDeblocking:
1170 				deblock = (VAProcFilterParameterBuffer *)base;
1171 
1172 				if (combination_check &&
1173 				    vpp_chain_caps[res_set].deblock_enabled != FILTER_ENABLED) {
1174 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The deblock is DISABLE for %d format\n", res_set);
1175 					vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
1176 					goto err;
1177 				} else {
1178 					/* check if the value is right */
1179 					strength = check_vpp_strength(deblock->value);
1180 					if (strength == INVALID_STRENGTH) {
1181 						vaStatus = VA_STATUS_ERROR_INVALID_VALUE;
1182 						goto err;
1183 					}
1184 					memcpy(&vpp_ctx->denoise_deblock_param,
1185 					       &vpp_strength[strength].denoise_deblock[res_set],
1186 					       sizeof(vpp_ctx->denoise_deblock_param));
1187 				}
1188 				break;
1189 
1190 			case VAProcFilterNoiseReduction:
1191 				denoise = (VAProcFilterParameterBuffer *)base;
1192 
1193 				if (combination_check &&
1194 				    vpp_chain_caps[res_set].denoise_enabled != FILTER_ENABLED) {
1195 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The denoise is DISABLE for %d format\n", res_set);
1196 					vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
1197 					goto err;
1198 				} else {
1199 					strength = check_vpp_strength(denoise->value);
1200 					if (strength == INVALID_STRENGTH) {
1201 						vaStatus = VA_STATUS_ERROR_INVALID_VALUE;
1202 						goto err;
1203 					}
1204 					memcpy(&vpp_ctx->denoise_deblock_param,
1205 					       &vpp_strength[strength].denoise_deblock[res_set],
1206 					       sizeof(vpp_ctx->denoise_deblock_param));
1207 				}
1208 				break;
1209 
1210 			case VAProcFilterSharpening:
1211 				sharpen = (VAProcFilterParameterBuffer *)base;
1212 
1213 				if (combination_check &&
1214 				    vpp_chain_caps[res_set].sharpen_enabled != FILTER_ENABLED) {
1215 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The sharpen is DISABLE for %d format\n", res_set);
1216 					vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
1217 					goto err;
1218 				} else {
1219 					strength = check_vpp_strength(sharpen->value);
1220 					if (strength == INVALID_STRENGTH) {
1221 						vaStatus = VA_STATUS_ERROR_INVALID_VALUE;
1222 						goto err;
1223 					}
1224 					memcpy(&vpp_ctx->sharpen_param,
1225 					      &vpp_strength[strength].sharpen[res_set],
1226 					       sizeof(vpp_ctx->sharpen_param));
1227 				}
1228 				break;
1229 
1230 			case VAProcFilterColorBalance:
1231 				balance = (VAProcFilterParameterBufferColorBalance *)base;
1232 
1233 				enabled_brightness = 0;
1234 				enabled_saturation = 0;
1235 
1236 				for (j = 0; j < buf->num_elements; ++j, ++balance) {
1237 					if (balance->attrib == VAProcColorBalanceAutoSaturation &&
1238 					    balance->value == MAX_VPP_AUTO_PARAM) {
1239 						enabled_saturation = 1;
1240 					} else if (balance->attrib == VAProcColorBalanceAutoBrightness &&
1241 						   balance->value == MAX_VPP_AUTO_PARAM) {
1242 						enabled_brightness = 1;
1243 					} else {
1244 						drv_debug_msg(VIDEO_DEBUG_ERROR, "The color_banlance do NOT support this attrib %d\n",
1245 							      balance->attrib);
1246 						vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1247 						goto err;
1248 					}
1249 				}
1250 
1251 				/* check filter chain */
1252 				if (combination_check &&
1253 				    vpp_chain_caps[res_set].color_balance_enabled != FILTER_ENABLED) {
1254 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The color_balance is DISABLE for %d format\n", res_set);
1255 					vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
1256 					goto err;
1257 				} else {
1258 					strength = MEDIUM_STRENGTH;
1259 					memcpy(&vpp_ctx->enhancer_param,
1260 					       &vpp_strength[strength].enhancer[res_set],
1261 					       sizeof(vpp_ctx->enhancer_param));
1262 					if (!enabled_saturation)
1263 						vpp_ctx->enhancer_param.chroma_amm = 0;
1264 					if (!enabled_brightness)
1265 						vpp_ctx->enhancer_param.luma_amm = 0;
1266 				}
1267 
1268 				break;
1269 
1270 			case VAProcFilterFrameRateConversion:
1271 				frc = (VAProcFilterParameterBufferFrameRateConversion *)base;
1272 
1273 				/* check frame rate */
1274 				ratio = frc->output_fps / (float)frc->input_fps;
1275 
1276 				if (!((ratio == 2 || ratio == 2.5 || ratio == 4) && frc->output_fps <= 60)) {
1277 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The FRC do NOT support the ration(%f) and fps(%d)\n",
1278 						      ratio, frc->output_fps);
1279 					vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1280 					goto err;
1281 				}
1282 
1283 				/* check the chain */
1284 				if (combination_check &&
1285 				    vpp_chain_caps[res_set].frc_enabled != FILTER_ENABLED) {
1286 					drv_debug_msg(VIDEO_DEBUG_ERROR, "The FRC is DISABLE for %d format\n", res_set);
1287 					vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
1288 					goto err;
1289 				}
1290 
1291 				break;
1292 			default:
1293 				drv_debug_msg(VIDEO_DEBUG_ERROR, "Do NOT support the filter type %d\n", base->type);
1294 				vaStatus = VA_STATUS_ERROR_UNKNOWN;
1295 				goto err;
1296 			}
1297 		}
1298 	} else {
1299 		drv_debug_msg(VIDEO_DEBUG_ERROR, "no HW support\n");
1300 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
1301 		goto err;
1302 	}
1303 err:
1304 	return vaStatus;
1305 }
1306 
vsp_set_pipeline(context_VPP_p ctx)1307 static VAStatus vsp_set_pipeline(context_VPP_p ctx)
1308 {
1309 	VAStatus vaStatus = VA_STATUS_SUCCESS;
1310 	vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf;
1311 	struct VssProcPipelineParameterBuffer *cell_pipeline_param = (struct VssProcPipelineParameterBuffer *)cmdbuf->pipeline_param_p;
1312 	unsigned int i, j, filter_count, check_filter = 0;
1313 	VAProcFilterParameterBufferBase *cur_param;
1314 	enum VssProcFilterType tmp;
1315 	psb_driver_data_p driver_data = ctx->obj_context->driver_data;
1316 
1317 	/* set intermediate buffer */
1318 	cell_pipeline_param->intermediate_buffer_size = VSP_INTERMEDIATE_BUF_SIZE;
1319 	cell_pipeline_param->intermediate_buffer_base = wsbmBOOffsetHint(ctx->intermediate_buf->drm_buf);
1320 
1321 	/* init pipeline cmd */
1322 	for (i = 0; i < VssProcPipelineMaxNumFilters; ++i)
1323 		cell_pipeline_param->filter_pipeline[i] = -1;
1324 	cell_pipeline_param->num_filters = 0;
1325 
1326 	filter_count = 0;
1327 
1328 	/* store filter buffer object */
1329 	if (ctx->num_filters != 0) {
1330 		for (i = 0; i < ctx->num_filters; ++i)
1331 			ctx->filter_buf[i] = BUFFER(ctx->filters[i]);
1332 	} else {
1333 		goto finished;
1334 	}
1335 
1336 	/* loop the filter, set correct pipeline param for FW */
1337 	for (i = 0; i < ctx->num_filters; ++i) {
1338 		cur_param = (VAProcFilterParameterBufferBase *)ctx->filter_buf[i]->buffer_data;
1339 		switch (cur_param->type) {
1340 		case VAProcFilterNone:
1341 			goto finished;
1342 			break;
1343 		case VAProcFilterNoiseReduction:
1344 		case VAProcFilterDeblocking:
1345 			cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterDenoise;
1346 			check_filter++;
1347 			break;
1348 		case VAProcFilterSharpening:
1349 			cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterSharpening;
1350 			break;
1351 		case VAProcFilterColorBalance:
1352 			cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterColorEnhancement;
1353 			break;
1354 		case VAProcFilterFrameRateConversion:
1355 			cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterFrameRateConversion;
1356 			break;
1357 		default:
1358 			cell_pipeline_param->filter_pipeline[filter_count++] = -1;
1359 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
1360 			goto out;
1361 		}
1362 	}
1363 
1364 	/* Denoise and Deblock is alternative */
1365 	if (check_filter >= 2) {
1366 		drv_debug_msg(VIDEO_DEBUG_ERROR, "Denoise and Deblock is alternative!\n");
1367 		cell_pipeline_param->filter_pipeline[filter_count++] = -1;
1368 		vaStatus = VA_STATUS_ERROR_UNKNOWN;
1369 		goto out;
1370 	}
1371 
1372 finished:
1373 	cell_pipeline_param->num_filters = filter_count;
1374 
1375 	/* reorder */
1376 	for (i = 1; i < filter_count; ++i)
1377 		for (j = i; j > 0; --j)
1378 			if (cell_pipeline_param->filter_pipeline[j] < cell_pipeline_param->filter_pipeline[j - 1]) {
1379 				/* swap */
1380 				tmp = cell_pipeline_param->filter_pipeline[j];
1381 				cell_pipeline_param->filter_pipeline[j] = cell_pipeline_param->filter_pipeline[j - 1];
1382 				cell_pipeline_param->filter_pipeline[j - 1] = tmp;
1383 			}
1384 
1385 	vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VPP_ID, &cmdbuf->param_mem, VssProcPipelineParameterCommand,
1386 				  ctx->pipeline_param_offset, sizeof(struct VssProcPipelineParameterBuffer));
1387 out:
1388 	return vaStatus;
1389 }
1390 
vsp_set_filter_param(context_VPP_p ctx)1391 static VAStatus vsp_set_filter_param(context_VPP_p ctx)
1392 {
1393 	VAStatus vaStatus = VA_STATUS_SUCCESS;
1394 	vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf;
1395 	struct VssProcDenoiseParameterBuffer *cell_denoiser_param = (struct VssProcDenoiseParameterBuffer *)cmdbuf->denoise_param_p;
1396 	struct VssProcColorEnhancementParameterBuffer *cell_enhancer_param = (struct VssProcColorEnhancementParameterBuffer *)cmdbuf->enhancer_param_p;
1397 	struct VssProcSharpenParameterBuffer *cell_sharpen_param = (struct VssProcSharpenParameterBuffer *)cmdbuf->sharpen_param_p;
1398 	struct VssProcFrcParameterBuffer *cell_proc_frc_param = (struct VssProcFrcParameterBuffer *)cmdbuf->frc_param_p;
1399 	VAProcFilterParameterBufferBase *cur_param = NULL;
1400 	VAProcFilterParameterBufferFrameRateConversion *frc_param = NULL;
1401 	unsigned int i;
1402 	float ratio;
1403 
1404 	for (i = 0; i < ctx->num_filters; ++i) {
1405 		cur_param = (VAProcFilterParameterBufferBase *)ctx->filter_buf[i]->buffer_data;
1406 		switch (cur_param->type) {
1407 		case VAProcFilterDeblocking:
1408 			memcpy(cell_denoiser_param,
1409 			       &ctx->denoise_deblock_param,
1410 			       sizeof(ctx->denoise_deblock_param));
1411 			cell_denoiser_param->type = VssProcDeblock;
1412 
1413 			vsp_cmdbuf_insert_command(cmdbuf,
1414 						  CONTEXT_VPP_ID,
1415 						  &cmdbuf->param_mem,
1416 						  VssProcDenoiseParameterCommand,
1417 						  ctx->denoise_param_offset,
1418 						  sizeof(struct VssProcDenoiseParameterBuffer));
1419 			break;
1420 
1421 		case VAProcFilterNoiseReduction:
1422 			memcpy(cell_denoiser_param,
1423 			       &ctx->denoise_deblock_param,
1424 			       sizeof(ctx->denoise_deblock_param));
1425 			cell_denoiser_param->type = VssProcDegrain;
1426 
1427 			vsp_cmdbuf_insert_command(cmdbuf,
1428 						  CONTEXT_VPP_ID,
1429 						  &cmdbuf->param_mem,
1430 						  VssProcDenoiseParameterCommand,
1431 						  ctx->denoise_param_offset,
1432 						  sizeof(struct VssProcDenoiseParameterBuffer));
1433 			break;
1434 
1435 		case VAProcFilterSharpening:
1436 			memcpy(cell_sharpen_param,
1437 			       &ctx->sharpen_param,
1438 			       sizeof(ctx->sharpen_param));
1439 
1440 			vsp_cmdbuf_insert_command(cmdbuf,
1441 						  CONTEXT_VPP_ID,
1442 						  &cmdbuf->param_mem,
1443 						  VssProcSharpenParameterCommand,
1444 						  ctx->sharpen_param_offset,
1445 						  sizeof(struct VssProcSharpenParameterBuffer));
1446 			break;
1447 
1448 		case VAProcFilterColorBalance:
1449 			memcpy(cell_enhancer_param,
1450 			       &ctx->enhancer_param,
1451 			       sizeof(ctx->enhancer_param));
1452 
1453 			vsp_cmdbuf_insert_command(cmdbuf,
1454 						  CONTEXT_VPP_ID,
1455 						  &cmdbuf->param_mem,
1456 						  VssProcColorEnhancementParameterCommand,
1457 						  ctx->enhancer_param_offset,
1458 						  sizeof(struct VssProcColorEnhancementParameterBuffer));
1459 
1460 			break;
1461 
1462 		case VAProcFilterFrameRateConversion:
1463 			ctx->frc_buf = ctx->filter_buf[i];
1464 
1465 			frc_param = (VAProcFilterParameterBufferFrameRateConversion *)ctx->filter_buf[i]->buffer_data;
1466 			ratio = frc_param->output_fps / (float)frc_param->input_fps;
1467 
1468 			/* set the FRC quality */
1469 			/* cell_proc_frc_param->quality = VssFrcMediumQuality; */
1470 			cell_proc_frc_param->quality = VssFrcHighQuality;
1471 
1472 			/* check if the input fps is in the range of HW capability */
1473 			if (ratio == 2)
1474 				cell_proc_frc_param->conversion_rate = VssFrc2xConversionRate;
1475 			else if (ratio == 2.5)
1476 				cell_proc_frc_param->conversion_rate = VssFrc2_5xConversionRate;
1477 			else if (ratio == 4)
1478 				cell_proc_frc_param->conversion_rate = VssFrc4xConversionRate;
1479 			else if (ratio == 1.25)
1480 				cell_proc_frc_param->conversion_rate = VssFrc1_25xConversionRate;
1481 			else {
1482 				drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid frame rate conversion ratio %f \n", ratio);
1483 				vaStatus = VA_STATUS_ERROR_UNKNOWN;
1484 				goto out;
1485 			}
1486 
1487 			vsp_cmdbuf_insert_command(cmdbuf,
1488 						  CONTEXT_VPP_ID,
1489 						  &cmdbuf->param_mem,
1490 						  VssProcFrcParameterCommand,
1491 						  ctx->frc_param_offset,
1492 						  sizeof(struct VssProcFrcParameterBuffer));
1493 			break;
1494 		default:
1495 			vaStatus = VA_STATUS_ERROR_UNKNOWN;
1496 			goto out;
1497 		}
1498 	}
1499 out:
1500 	return vaStatus;
1501 }
1502 
check_resolution(int width,int height)1503 static int check_resolution(int width, int height)
1504 {
1505 	int ret;
1506 	int image_area;
1507 
1508 	if (height < MIN_SUPPORTED_HEIGHT || height > MAX_SUPPORTED_HEIGHT)
1509 		return NOT_SUPPORTED_RESOLUTION;
1510 
1511 	image_area = height * width;
1512 
1513 	if (image_area <= QVGA_AREA)
1514 		ret = QCIF_TO_QVGA;
1515 	else if (image_area <= VGA_AREA)
1516 		ret = QVGA_TO_VGA;
1517 	else if (image_area <= SD_AREA)
1518 		ret = VGA_TO_SD;
1519 	else if (image_area <= HD720P_AREA)
1520 		ret = SD_TO_720P;
1521 	else if (image_area <= HD1080P_AREA)
1522 		ret = HD720P_TO_1080P;
1523 	else
1524 		ret = NOT_SUPPORTED_RESOLUTION;
1525 
1526 	return ret;
1527 }
1528 
1529 /*
1530  * The strength area is:
1531  *
1532  * 0______33______66______100
1533  *   LOW     MED     HIGH
1534  *
1535  * MIN=0; MAX=100; STEP=33
1536  */
check_vpp_strength(int value)1537 static int check_vpp_strength(int value)
1538 {
1539 	if (value < MIN_VPP_PARAM || value > MAX_VPP_PARAM)
1540 		return INVALID_STRENGTH;
1541 
1542 	if (value >= MIN_VPP_PARAM &&
1543 	    value < MIN_VPP_PARAM + STEP_VPP_PARAM)
1544 		return LOW_STRENGTH;
1545 	else if (value >= MIN_VPP_PARAM + STEP_VPP_PARAM &&
1546 		 value < MIN_VPP_PARAM + 2 * STEP_VPP_PARAM)
1547 		return MEDIUM_STRENGTH;
1548 	else
1549 		return HIGH_STRENGTH;
1550 }
1551