1 /*
2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Binglin Chen <binglin.chen@intel.com>
26 *
27 */
28
29 #include "vsp_VPP.h"
30 #include "psb_buffer.h"
31 #include "psb_surface.h"
32 #include "vsp_cmdbuf.h"
33 #include "psb_drv_debug.h"
34 #include "vsp_compose.h"
35
36 #include <strings.h>
37
38 #define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
39 #define INIT_CONTEXT_VPP context_VPP_p ctx = (context_VPP_p) obj_context->format_data;
40 #define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
41 #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
42 #define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
43
44 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id ))
45
46 #define KB 1024
47 #define MB (KB * KB)
48 #define VSP_CONTEXT_BUF_SIZE (60*KB)
49 #define VSP_INTERMEDIATE_BUF_SIZE (29*MB)
50
51 #define MAX_VPP_PARAM (100)
52 #define MIN_VPP_PARAM (0)
53 #define STEP_VPP_PARAM (33)
54 #define MAX_VPP_AUTO_PARAM (1)
55 #define MIN_VPP_AUTO_PARAM (0)
56 #define STEP_VPP_AUTO_PARAM (1)
57
58 #define VSP_FORWARD_REF_NUM 3
59
60 #define VSP_COLOR_ENHANCE_FEATURES 2
61
62 #define ALIGN_TO_128(value) ((value + 128 - 1) & ~(128 - 1))
63 #define ALIGN_TO_16(value) ((value + 16 - 1) & ~(16 - 1))
64
65 #define QVGA_AREA (320 * 240)
66 #define VGA_AREA (640 * 480)
67 #define SD_AREA (720 * 576)
68 #define HD720P_AREA (1280 * 720)
69 #define HD1080P_AREA (1920 * 1088)
70
71 #define MIN_SUPPORTED_HEIGHT 96
72 #define MAX_SUPPORTED_HEIGHT 1088
73
74 /**
75 * The number of supported filter is 5:
76 * VAProcFilterDeblocking
77 * VAProcFilterNoiseReduction
78 * VAProcFilterSharpening
79 * VAProcFilterColorBalance
80 * VAProcFilterFrameRateConversion
81 */
82 #define VSP_SUPPORTED_FILTERS_NUM 5
83
84 /* The size of supported color standard */
85 #define COLOR_STANDARDS_NUM 1
86
87 enum resolution_set {
88 NOT_SUPPORTED_RESOLUTION = -1,
89 QCIF_TO_QVGA = 0,
90 QVGA_TO_VGA,
91 VGA_TO_SD,
92 SD_TO_720P,
93 HD720P_TO_1080P,
94 RESOLUTION_SET_NUM
95 };
96
97 struct vpp_chain_capability {
98 int frc_enabled;
99 int sharpen_enabled;
100 int color_balance_enabled;
101 int denoise_enabled;
102 int deblock_enabled;
103 };
104
105 enum filter_status {
106 FILTER_DISABLED = 0,
107 FILTER_ENABLED
108 };
109
110 struct vpp_chain_capability vpp_chain_caps[RESOLUTION_SET_NUM] = {
111 [HD720P_TO_1080P] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_DISABLED, FILTER_DISABLED},
112 [SD_TO_720P] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_DISABLED, FILTER_DISABLED},
113 [VGA_TO_SD] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_DISABLED, FILTER_DISABLED},
114 [QVGA_TO_VGA] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED},
115 [QCIF_TO_QVGA] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_ENABLED}
116 };
117
118 struct filter_strength {
119 struct VssProcDenoiseParameterBuffer denoise_deblock[RESOLUTION_SET_NUM];
120 struct VssProcColorEnhancementParameterBuffer enhancer[RESOLUTION_SET_NUM];
121 struct VssProcSharpenParameterBuffer sharpen[RESOLUTION_SET_NUM];
122 };
123
124 enum filter_strength_type {
125 INVALID_STRENGTH = -1,
126 LOW_STRENGTH = 0,
127 MEDIUM_STRENGTH,
128 HIGH_STRENGTH,
129 STRENGTH_NUM
130 };
131
132 #define SHARPEN_ON (1)
133
134 struct filter_strength vpp_strength[STRENGTH_NUM] = {
135 [LOW_STRENGTH] = {
136 /* structure:
137 * type(0-Denoise,1-Deblock), value_thr, cnt_thr, coef, temp_thr1, temp_thr2, _pad[2]
138 */
139 .denoise_deblock = {
140 [QCIF_TO_QVGA] = {1, 15, 47, 35, 0, 0, {0, 0}},
141 [QVGA_TO_VGA] = {0, 7, 48, 47, 0, 0, {0, 0}},
142 [VGA_TO_SD] = {0, 10, 8, 9, 1, 3, {0, 0}},
143 [SD_TO_720P] = {0, 10, 48, 47, 0, 0, {0, 0}},
144 [HD720P_TO_1080P] = {0, 10, 48, 47, 0, 0, {0, 0}}
145 },
146 /* structure:
147 * temp_detect, temp_correct, clip_thr, mid_thr, luma_amm, chroma_amm, _pad[2]
148 */
149 .enhancer = {
150 [QCIF_TO_QVGA] = {200, 100, 1, 42, 40, 60, {0, 0}},
151 [QVGA_TO_VGA] = {220, 180, 1, 42, 40, 60, {0, 0}},
152 [VGA_TO_SD] = {220, 200, 1, 42, 40, 60, {0, 0}},
153 [SD_TO_720P] = {100, 100, 5, 33, 0, 0, {0, 0}},
154 [HD720P_TO_1080P] = {100, 100, 5, 33, 0, 0, {0, 0}}
155 },
156 .sharpen = {
157 [QCIF_TO_QVGA] = { .quality = SHARPEN_ON },
158 [QVGA_TO_VGA] = { .quality = SHARPEN_ON },
159 [VGA_TO_SD] = { .quality = SHARPEN_ON },
160 [SD_TO_720P] = { .quality = SHARPEN_ON },
161 [HD720P_TO_1080P] = { .quality = SHARPEN_ON }
162 }
163 },
164 [MEDIUM_STRENGTH] = {
165 .denoise_deblock = {
166 [QCIF_TO_QVGA] = {1, 25, 47, 12, 0, 0, {0, 0}},
167 [QVGA_TO_VGA] = {0, 10, 48, 47, 0, 0, {0, 0}},
168 [VGA_TO_SD] = {0, 20, 8, 9, 2, 4, {0, 0}},
169 [SD_TO_720P] = {0, 10, 48, 47, 0, 0, {0, 0}},
170 [HD720P_TO_1080P] = {0, 10, 48, 47, 0, 0, {0, 0}}
171 },
172 .enhancer = {
173 [QCIF_TO_QVGA] = {100, 100, 1, 33, 100, 100, {0, 0}},
174 [QVGA_TO_VGA] = {100, 180, 1, 33, 100, 100, {0, 0}},
175 [VGA_TO_SD] = {100, 200, 1, 33, 100, 100, {0, 0}},
176 [SD_TO_720P] = {100, 100, 5, 33, 0, 0, {0, 0}},
177 [HD720P_TO_1080P] = {100, 100, 5, 33, 0, 0, {0, 0}}
178 },
179 .sharpen = {
180 [QCIF_TO_QVGA] = { .quality = SHARPEN_ON },
181 [QVGA_TO_VGA] = { .quality = SHARPEN_ON },
182 [VGA_TO_SD] = { .quality = SHARPEN_ON },
183 [SD_TO_720P] = { .quality = SHARPEN_ON },
184 [HD720P_TO_1080P] = { .quality = SHARPEN_ON }
185 }
186 },
187 [HIGH_STRENGTH] = {
188 .denoise_deblock = {
189 [QCIF_TO_QVGA] = {1, 30, 40, 10, 0, 0, {0, 0}},
190 [QVGA_TO_VGA] = {0, 15, 45, 25, 0, 0, {0, 0}},
191 [VGA_TO_SD] = {0, 20, 7, 5, 3, 6, {0, 0}},
192 [SD_TO_720P] = {0, 10, 48, 47, 0, 0, {0, 0}},
193 [HD720P_TO_1080P] = {0, 10, 48, 47, 0, 0, {0, 0}}
194 },
195 .enhancer = {
196 [QCIF_TO_QVGA] = {100, 100, 5, 33, 150, 200, {0, 0}},
197 [QVGA_TO_VGA] = {100, 180, 5, 33, 150, 200, {0, 0}},
198 [VGA_TO_SD] = {100, 200, 5, 33, 100, 150, {0, 0}},
199 [SD_TO_720P] = {100, 100, 5, 33, 0, 0, {0, 0}},
200 [HD720P_TO_1080P] = {100, 100, 5, 33, 0, 0, {0, 0}}
201 },
202 .sharpen = {
203 [QCIF_TO_QVGA] = { .quality = SHARPEN_ON },
204 [QVGA_TO_VGA] = { .quality = SHARPEN_ON },
205 [VGA_TO_SD] = { .quality = SHARPEN_ON },
206 [SD_TO_720P] = { .quality = SHARPEN_ON },
207 [HD720P_TO_1080P] = { .quality = SHARPEN_ON }
208 }
209 }
210 };
211
212 static void vsp_VPP_DestroyContext(object_context_p obj_context);
213 static VAStatus vsp_set_pipeline(context_VPP_p ctx);
214 static VAStatus vsp_set_filter_param(context_VPP_p ctx);
215 static VAStatus vsp__VPP_check_legal_picture(object_context_p obj_context, object_config_p obj_config);
216 static int check_resolution(int width, int height);
217 static int check_vpp_strength(int value);
218
vsp_VPP_QueryConfigAttributes(VAProfile __maybe_unused profile,VAEntrypoint __maybe_unused entrypoint,VAConfigAttrib __maybe_unused * attrib_list,int __maybe_unused num_attribs)219 static void vsp_VPP_QueryConfigAttributes(
220 VAProfile __maybe_unused profile,
221 VAEntrypoint __maybe_unused entrypoint,
222 VAConfigAttrib __maybe_unused *attrib_list,
223 int __maybe_unused num_attribs)
224 {
225 /* No VPP specific attributes */
226 return;
227 }
228
vsp_VPP_ValidateConfig(object_config_p obj_config)229 static VAStatus vsp_VPP_ValidateConfig(
230 object_config_p obj_config)
231 {
232 int i;
233 /* Check all attributes */
234 for (i = 0; i < obj_config->attrib_count; i++) {
235 switch (obj_config->attrib_list[i].type) {
236 case VAConfigAttribRTFormat:
237 /* Ignore */
238 break;
239
240 default:
241 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
242 }
243 }
244
245 return VA_STATUS_SUCCESS;
246 }
247
vsp__VPP_check_legal_picture(object_context_p obj_context,object_config_p obj_config)248 static VAStatus vsp__VPP_check_legal_picture(object_context_p obj_context, object_config_p obj_config)
249 {
250 VAStatus vaStatus = VA_STATUS_SUCCESS;
251
252 if (NULL == obj_context) {
253 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
254 DEBUG_FAILURE;
255 return vaStatus;
256 }
257
258 if (NULL == obj_config) {
259 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
260 DEBUG_FAILURE;
261 return vaStatus;
262 }
263
264 return vaStatus;
265 }
266
vsp_VPP_CreateContext(object_context_p obj_context,object_config_p obj_config)267 static VAStatus vsp_VPP_CreateContext(
268 object_context_p obj_context,
269 object_config_p obj_config)
270 {
271 VAStatus vaStatus = VA_STATUS_SUCCESS;
272 context_VPP_p ctx;
273 int i;
274
275 /* Validate flag */
276 /* Validate picture dimensions */
277 vaStatus = vsp__VPP_check_legal_picture(obj_context, obj_config);
278 if (VA_STATUS_SUCCESS != vaStatus) {
279 DEBUG_FAILURE;
280 return vaStatus;
281 }
282
283 ctx = (context_VPP_p) calloc(1, sizeof(struct context_VPP_s));
284 if (NULL == ctx) {
285 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
286 DEBUG_FAILURE;
287 return vaStatus;
288 }
289
290 ctx->filters = NULL;
291 ctx->num_filters = 0;
292
293 ctx->frc_buf = NULL;
294
295 /* set size */
296 ctx->param_sz = 0;
297 ctx->pic_param_sz = ALIGN_TO_128(sizeof(struct VssProcPictureParameterBuffer));
298 ctx->param_sz += ctx->pic_param_sz;
299 ctx->end_param_sz = ALIGN_TO_128(sizeof(struct VssProcPictureParameterBuffer));
300 ctx->param_sz += ctx->end_param_sz;
301
302 ctx->pipeline_param_sz = ALIGN_TO_128(sizeof(struct VssProcPipelineParameterBuffer));
303 ctx->param_sz += ctx->pipeline_param_sz;
304 ctx->denoise_param_sz = ALIGN_TO_128(sizeof(struct VssProcDenoiseParameterBuffer));
305 ctx->param_sz += ctx->denoise_param_sz;
306 ctx->enhancer_param_sz = ALIGN_TO_128(sizeof(struct VssProcColorEnhancementParameterBuffer));
307 ctx->param_sz += ctx->enhancer_param_sz;
308 ctx->sharpen_param_sz = ALIGN_TO_128(sizeof(struct VssProcSharpenParameterBuffer));
309 ctx->param_sz += ctx->sharpen_param_sz;
310 ctx->frc_param_sz = ALIGN_TO_128(sizeof(struct VssProcFrcParameterBuffer));
311 ctx->param_sz += ctx->frc_param_sz;
312 ctx->compose_param_sz = ALIGN_TO_128(sizeof(struct VssWiDi_ComposeSequenceParameterBuffer));
313 ctx->param_sz += ctx->compose_param_sz;
314
315 /* set offset */
316 ctx->pic_param_offset = 0;
317 ctx->end_param_offset = ctx->pic_param_offset + ctx->pic_param_sz;
318 ctx->pipeline_param_offset = ctx->end_param_offset + ctx->end_param_sz;
319 ctx->denoise_param_offset = ctx->pipeline_param_offset + ctx->pipeline_param_sz;
320 ctx->enhancer_param_offset = ctx->denoise_param_offset + ctx->denoise_param_sz;
321 ctx->sharpen_param_offset = ctx->enhancer_param_offset + ctx->enhancer_param_sz;
322 ctx->frc_param_offset = ctx->sharpen_param_offset + ctx->sharpen_param_sz;
323 /* For composer, it'll start on 0 */
324 ctx->compose_param_offset = 0;
325
326 /* create intermediate buffer */
327 ctx->intermediate_buf = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s));
328 if (NULL == ctx->intermediate_buf) {
329 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
330 DEBUG_FAILURE;
331 goto out;
332 }
333 vaStatus = psb_buffer_create(obj_context->driver_data, VSP_INTERMEDIATE_BUF_SIZE, psb_bt_vpu_only, ctx->intermediate_buf);
334 if (VA_STATUS_SUCCESS != vaStatus) {
335 goto out;
336 }
337
338 obj_context->format_data = (void*) ctx;
339 ctx->obj_context = obj_context;
340
341 for (i = 0; i < obj_config->attrib_count; ++i) {
342 if (VAConfigAttribRTFormat == obj_config->attrib_list[i].type) {
343 switch (obj_config->attrib_list[i].value) {
344 case VA_RT_FORMAT_YUV420:
345 ctx->format = VSP_NV12;
346 break;
347 case VA_RT_FORMAT_YUV422:
348 ctx->format = VSP_NV16;
349 default:
350 ctx->format = VSP_NV12;
351 break;
352 }
353 break;
354 }
355 }
356
357 bzero(&ctx->denoise_deblock_param, sizeof(ctx->denoise_deblock_param));
358 bzero(&ctx->enhancer_param, sizeof(ctx->enhancer_param));
359 bzero(&ctx->sharpen_param, sizeof(ctx->sharpen_param));
360
361 return vaStatus;
362 out:
363 vsp_VPP_DestroyContext(obj_context);
364
365 if (ctx) {
366 if(ctx->intermediate_buf != NULL)
367 free(ctx->intermediate_buf);
368 free(ctx);
369 ctx = NULL;
370 }
371
372 return vaStatus;
373 }
374
vsp_VPP_DestroyContext(object_context_p obj_context)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
vsp__VPP_process_pipeline_param(context_VPP_p ctx,object_context_p obj_context,object_buffer_p obj_buffer)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
vsp_VPP_RenderPicture(object_context_p obj_context,object_buffer_p * buffers,int num_buffers)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
vsp_VPP_BeginPicture(object_context_p obj_context)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
vsp_VPP_EndPicture(object_context_p obj_context)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
vsp_QueryVideoProcFilters(VADriverContextP ctx,VAContextID context,VAProcFilterType * filters,unsigned int * num_filters)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
vsp_QueryVideoProcFilterCaps(VADriverContextP ctx,VAContextID context,VAProcFilterType type,void * filter_caps,unsigned int * num_filter_caps)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
vsp_QueryVideoProcPipelineCaps(VADriverContextP ctx,VAContextID context,VABufferID * filters,unsigned int num_filters,VAProcPipelineCaps * pipeline_caps)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
vsp_set_pipeline(context_VPP_p ctx)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
vsp_set_filter_param(context_VPP_p ctx)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
check_resolution(int width,int height)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 */
check_vpp_strength(int value)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