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