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