Home | History | Annotate | Download | only in src
      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 (at) 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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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  */
   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