vsp_vp8.c revision ac309081b871fae9abf0c2c6827979ec83b09cf3
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 * Zhangfei Zhang <zhangfei.zhang@intel.com> 26 * Mingruo Sun <mingruo.sun@intel.com> 27 * 28 */ 29#include "vsp_VPP.h" 30#include "vsp_vp8.h" 31#include "psb_buffer.h" 32#include "psb_surface.h" 33#include "vsp_cmdbuf.h" 34#include "psb_drv_debug.h" 35#include "va/va_enc_vp8.h" 36 37#define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; 38#define INIT_CONTEXT_VPP context_VPP_p ctx = (context_VPP_p) obj_context->format_data; 39#define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id )) 40#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) 41#define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id )) 42 43#define SURFACE(id) ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id )) 44 45#define KB 1024 46#define MB (KB * KB) 47#define VSP_VP8ENC_STATE_SIZE (48*MB) 48 49#define ALIGN_TO_128(value) ((value + 128 - 1) & ~(128 - 1)) 50 51#define REF_FRAME_WIDTH 1920 52#define REF_FRAME_HEIGHT 1088 53#define REF_FRAME_BORDER 32 54 55#define VP8_ENC_CBR 1 56#define VP8_ENC_CBR_HRD 0 57 58#define XMEM_FRAME_BUFFER_SIZE_IN_BYTE ((REF_FRAME_WIDTH + 2 * REF_FRAME_BORDER) * (REF_FRAME_HEIGHT + 2 * REF_FRAME_BORDER) + \ 59 2 * ((REF_FRAME_WIDTH + 2 * REF_FRAME_BORDER) >> 1) * (REF_FRAME_HEIGHT / 2 + REF_FRAME_BORDER)) // Allocated for HD 60 61enum filter_status { 62 FILTER_DISABLED = 0, 63 FILTER_ENABLED 64}; 65 66typedef struct _Ref_frame_surface { 67 struct VssProcPictureVP8 ref_frame_buffers[4]; 68} ref_frame_surface; 69 70#define FUNCTION_NAME \ 71 printf("ENTER %s.\n",__FUNCTION__); 72 73#define EXIT_FUNCTION_NAME \ 74 printf("EXIT %s.\n",__FUNCTION__); 75 76 77typedef union{ 78 struct { 79 /* force this frame to be a keyframe */ 80 unsigned int force_kf : 1; 81 /* don't reference the last frame */ 82 unsigned int no_ref_last : 1; 83 /* don't reference the golden frame */ 84 unsigned int no_ref_gf : 1; 85 /* don't reference the alternate reference frame */ 86 unsigned int no_ref_arf : 1; 87 88 unsigned int upd_last : 1; 89 unsigned int upd_gf : 2; 90 unsigned int upd_arf : 2; 91 unsigned int no_upd_last : 1; 92 unsigned int no_upd_gf : 1; 93 unsigned int no_upd_arf : 1; 94 unsigned int no_upd_entropy : 1; 95 } bits; 96 unsigned int value; 97 } vp8_fw_pic_flags; 98 99 100static void vsp_VP8_DestroyContext(object_context_p obj_context); 101 102static VAStatus vsp__VP8_check_legal_picture(object_context_p obj_context, object_config_p obj_config); 103 104static void vsp_VP8_QueryConfigAttributes( 105 VAProfile profile, 106 VAEntrypoint entrypoint, 107 VAConfigAttrib *attrib_list, 108 int num_attribs) 109{ 110 int i; 111 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s\n", __FUNCTION__); 112 113 for (i = 0; i < num_attribs; i++) { 114 switch (attrib_list[i].type) { 115 case VAConfigAttribRTFormat: 116 break; 117 case VAConfigAttribRateControl: 118 attrib_list[i].value = VA_RC_CBR | VA_RC_VBR; 119 break; 120 case VAConfigAttribEncAutoReference: 121 attrib_list[i].value = 1; 122 break; 123 case VAConfigAttribEncMaxRefFrames: 124 attrib_list[i].value = 4; 125 break; 126 127 default: 128 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED; 129 break; 130 } 131 } 132} 133 134static VAStatus vsp_VP8_ValidateConfig( 135 object_config_p obj_config) 136{ 137 int i; 138 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s\n", __FUNCTION__); 139 140 /* Check all attributes */ 141 for (i = 0; i < obj_config->attrib_count; i++) { 142 switch (obj_config->attrib_list[i].type) { 143 case VAConfigAttribRTFormat: 144 /* Ignore */ 145 break; 146 case VAConfigAttribRateControl: 147 break; 148 case VAConfigAttribEncAutoReference: 149 break; 150 case VAConfigAttribEncMaxRefFrames: 151 break; 152 153 default: 154 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; 155 } 156 } 157 158 return VA_STATUS_SUCCESS; 159} 160 161static VAStatus vsp_VP8_CreateContext( 162 object_context_p obj_context, 163 object_config_p obj_config) 164{ 165 VAStatus vaStatus = VA_STATUS_SUCCESS; 166 /* currently vp8 will use vpp's context since they will use the same cmdbuf */ 167 context_VPP_p ctx; 168 int i; 169 170 ctx = (context_VPP_p) calloc(1, sizeof(struct context_VPP_s)); 171 if (NULL == ctx) { 172 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 173 DEBUG_FAILURE; 174 return vaStatus; 175 } 176 177 for (i = 0; i < obj_config->attrib_count; i++) { 178 if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) { 179 ctx->rc_mode = obj_config->attrib_list[i].value; 180 break; 181 } 182 } 183 184 /* set size */ 185 ctx->param_sz = 0; 186 ctx->pic_param_sz = ALIGN_TO_128(sizeof(struct VssVp8encPictureParameterBuffer)); 187 ctx->param_sz += ctx->pic_param_sz; 188 ctx->seq_param_sz = ALIGN_TO_128(sizeof(struct VssVp8encSequenceParameterBuffer)); 189 ctx->param_sz += ctx->seq_param_sz; 190 ctx->ref_param_sz = ALIGN_TO_128(sizeof(ref_frame_surface)); 191 ctx->param_sz += ctx->ref_param_sz; 192 193 /* set offset */ 194 ctx->pic_param_offset = 0; 195 ctx->seq_param_offset = ctx->pic_param_sz; 196 ctx->ref_param_offset = ctx->pic_param_sz + ctx->seq_param_sz; 197 198 ctx->min_qp = 4; 199 ctx->max_qp = 63; 200 ctx->rc_undershoot = 100; 201 ctx->buffer_size = 6000; 202 ctx->initial_buffer_fullness = 4000; 203 ctx->optimal_buffer_fullness = 5000; 204 205 ctx->context_buf = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s)); 206 if (NULL == ctx->context_buf) { 207 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 208 DEBUG_FAILURE; 209 goto out; 210 } 211 212 vaStatus = psb_buffer_create(obj_context->driver_data, VSP_VP8ENC_STATE_SIZE, psb_bt_vpu_only, ctx->context_buf); 213 214 if (VA_STATUS_SUCCESS != vaStatus) { 215 goto out; 216 } 217 218 obj_context->format_data = (void*) ctx; 219 ctx->obj_context = obj_context; 220 221 return vaStatus; 222 223out: 224 vsp_VP8_DestroyContext(obj_context); 225 226 if (ctx) 227 free(ctx); 228 229 return vaStatus; 230} 231 232static void vsp_VP8_DestroyContext( 233 object_context_p obj_context) 234{ 235 INIT_CONTEXT_VPP; 236 237 if (ctx->context_buf) { 238 psb_buffer_destroy(ctx->context_buf); 239 free(ctx->context_buf); 240 ctx->context_buf = NULL; 241 } 242 243 if (ctx->filters) { 244 free(ctx->filters); 245 ctx->num_filters = 0; 246 } 247 248 free(obj_context->format_data); 249 obj_context->format_data = NULL; 250} 251 252static VAStatus vsp_vp8_process_seqence_param( 253 context_VPP_p ctx, 254 object_buffer_p obj_buffer) 255{ 256 257 VAStatus vaStatus = VA_STATUS_SUCCESS; 258 vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf; 259 int i; 260 int ref_frame_width, ref_frame_height; 261 262 VAEncSequenceParameterBufferVP8 *va_seq = 263 (VAEncSequenceParameterBufferVP8 *) obj_buffer->buffer_data; 264 struct VssVp8encSequenceParameterBuffer *seq = 265 (struct VssVp8encSequenceParameterBuffer *)cmdbuf->seq_param_p; 266 267 ref_frame_surface *ref = 268 (struct ref_frame_surface*)cmdbuf->ref_param_p; 269 270 ctx->frame_width = va_seq->frame_width; 271 ctx->frame_height = va_seq->frame_height; 272 273 /*cmd structures initializations*/ 274 seq->frame_width = va_seq->frame_width; 275 seq->frame_height = va_seq->frame_height; 276 seq->rc_target_bitrate = va_seq->bits_per_second / 1000; 277 seq->max_intra_rate = 0; 278 seq->rc_undershoot_pct = ctx->rc_undershoot; 279 seq->rc_overshoot_pct = 100; 280 /* FIXME: API doc says max 5000, but for current default test vector we still use 6000 */ 281 seq->rc_buf_sz = ctx->buffer_size; 282 seq->rc_buf_initial_sz = ctx->initial_buffer_fullness; 283 seq->rc_buf_optimal_sz = ctx->optimal_buffer_fullness; 284 seq->rc_min_quantizer = ctx->min_qp; 285 seq->rc_max_quantizer = ctx->max_qp; 286 seq->kf_max_dist = va_seq->kf_max_dist; 287 seq->kf_min_dist = va_seq->kf_min_dist; 288 seq->frame_rate = ctx->frame_rate; 289 seq->error_resilient = va_seq->error_resilient; 290 seq->num_token_partitions = 2; // (log2: 2^2 = 4) 291 seq->rc_end_usage = (ctx->rc_mode == VA_RC_CBR) ? VP8_ENC_CBR_HRD : VP8_ENC_CBR; /* CBR */ 292 seq->kf_mode = va_seq->kf_auto; /* AUTO */ 293 seq->cyclic_intra_refresh = 0; 294 295 seq->concatenate_partitions = 1; //Make 0 not to concatenate partitions 296 297 ref_frame_width = (ctx->frame_width + 2 * 32 + 63) & (~63); 298 ref_frame_height = (ctx->frame_height + 2 * 32 + 63) & (~63); 299 300 ctx->frame_rate = seq->frame_rate; 301 ctx->bits_per_second = va_seq->bits_per_second; 302 303 ctx->vp8_seq_param = * seq; 304 305 vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VP8_ID, &cmdbuf->param_mem, 306 VssVp8encSetSequenceParametersCommand, 307 ctx->seq_param_offset, 308 sizeof(struct VssVp8encSequenceParameterBuffer)); 309 ctx->vp8_seq_cmd_send = 1; 310 311 /* pass 4 ref frame surface to kernel driver */ 312 for (i = 0; i < 4; i++) { 313 ref->ref_frame_buffers[i].surface_id = va_seq->reference_frames[i]; 314 ref->ref_frame_buffers[i].width = ref_frame_width; 315 ref->ref_frame_buffers[i].height = ref_frame_height; 316 } 317 318 for (i = 0; i < 4; i++) { 319 object_surface_p ref_surf = SURFACE(va_seq->reference_frames[i]); 320 if (!ref_surf) 321 return VA_STATUS_ERROR_UNKNOWN; 322 ref_surf->is_ref_surface = 2; 323 324 vsp_cmdbuf_reloc_pic_param(&(ref->ref_frame_buffers[i].base), 325 ctx->ref_param_offset, 326 &(ref_surf->psb_surface->buf), 327 cmdbuf->param_mem_loc, ref); 328 } 329 330 vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VP8_ID, 331 &cmdbuf->param_mem, Vss_Sys_Ref_Frame_COMMAND, 332 ctx->ref_param_offset, 333 sizeof(ref_frame_surface)); 334 335 return vaStatus; 336} 337 338static VAStatus vsp_vp8_process_dynamic_seqence_param( 339 context_VPP_p ctx) 340{ 341 342 VAStatus vaStatus = VA_STATUS_SUCCESS; 343 vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf; 344 int i; 345 int ref_frame_width, ref_frame_height; 346 347 struct VssVp8encSequenceParameterBuffer *seq = 348 (struct VssVp8encSequenceParameterBuffer *)cmdbuf->seq_param_p; 349 350 if( ctx->vp8_seq_cmd_send ) 351 { //just change the command buffer 352 seq->frame_rate = ctx->frame_rate; 353 seq->rc_min_quantizer = ctx->min_qp; 354 seq->cyclic_intra_refresh = ctx->cyclic_intra_refresh; 355 seq->rc_target_bitrate = ctx->bits_per_second / 1000 ; 356 seq->max_intra_rate = ctx->max_frame_size *30 * 1000 / ctx->bits_per_second; 357 return vaStatus; 358 } 359 360 *seq = ctx->vp8_seq_param ; 361 seq->frame_rate = ctx->frame_rate; 362 seq->rc_min_quantizer = ctx->min_qp; 363 seq->cyclic_intra_refresh = ctx->cyclic_intra_refresh; 364 seq->rc_target_bitrate = ctx->bits_per_second / 1000 ; 365 seq->max_intra_rate = ctx->max_frame_size *30 * 1000 / ctx->bits_per_second; 366 367 368 vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VP8_ID, &cmdbuf->param_mem, 369 VssVp8encSetSequenceParametersCommand, 370 ctx->seq_param_offset, 371 sizeof(struct VssVp8encSequenceParameterBuffer)); 372 373 return vaStatus; 374} 375 376 377static VAStatus vsp_vp8_process_picture_param( 378 psb_driver_data_p driver_data, 379 context_VPP_p ctx, 380 object_buffer_p obj_buffer, 381 VASurfaceID surface_id) 382 383{ 384 VAStatus vaStatus = VA_STATUS_SUCCESS; 385 vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf; 386 387 VAEncSequenceParameterBufferVP8 *va_seq = 388 (VAEncSequenceParameterBufferVP8 *) obj_buffer->buffer_data; 389 VAEncPictureParameterBufferVP8 *va_pic = 390 (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data; 391 struct VssVp8encPictureParameterBuffer *pic = cmdbuf->pic_param_p; 392 struct VssVp8encSequenceParameterBuffer *seq = 393 (struct VssVp8encSequenceParameterBuffer *)cmdbuf->seq_param_p; 394 VACodedBufferSegment *p = &obj_buffer->codedbuf_mapinfo[0]; 395 int ref_frame_width, ref_frame_height; 396 397 ref_frame_width = (ctx->frame_width + 2 * 32 + 63) & (~63); 398 ref_frame_height = (ctx->frame_height + 2 * 32 + 63) & (~63); 399 400 //map parameters 401 object_buffer_p pObj = BUFFER(va_pic->coded_buf); //tobe modified 402 if (!pObj) 403 return VA_STATUS_ERROR_UNKNOWN; 404 405 object_surface_p src_surface = SURFACE(surface_id); 406 407 pic->input_frame.surface_id = surface_id; 408 pic->input_frame.irq = 1; 409 pic->input_frame.height = ctx->frame_height; 410 pic->input_frame.width = ctx->frame_width; 411 /* NOTE: In VIED API doc, stride must be the nearest integer multiple of 32 */ 412 /* use vaCreateSurfaceWithAttribute with VAExternalMemoryNULL to create surface*/ 413 //pic->input_frame.stride = (ctx->frame_width + 31) & (~31); 414 pic->input_frame.stride = ctx->obj_context->current_render_target->psb_surface->stride; 415 pic->input_frame.format = 0; /* TODO: Specify NV12 = 0 */ 416 417 pic->recon_frame.irq = 0; 418 pic->recon_frame.width = ref_frame_width; 419 pic->recon_frame.height = ref_frame_height; 420 421 pic->version = 0; 422#if 0 423 pic->pic_flags = (1<< 2) | /* corresponds to VP8_EFLAG_NO_REF_GF */ 424 (1<< 3) | /* corresponds to VP8_EFLAG_NO_REF_ARF */ 425 (1<< 12); /* corresponds to ~VP8_EFLAG_NO_UPD_ENTROPY */ 426#else 427 vp8_fw_pic_flags flags; 428 flags.value =0; 429 430 flags.bits.force_kf = va_pic->ref_flags.bits.force_kf; 431 flags.bits.no_ref_last = va_pic->ref_flags.bits.no_ref_last; 432 flags.bits.no_ref_gf = va_pic->ref_flags.bits.no_ref_gf; 433 flags.bits.no_ref_arf = va_pic->ref_flags.bits.no_ref_arf; 434 flags.bits.upd_last = va_pic->pic_flags.bits.refresh_last; 435 flags.bits.upd_gf =0;//= va_pic->pic_flags.bits.refresh_golden_frame; 436 flags.bits.upd_arf =0;//= va_pic->pic_flags.bits.refresh_alternate_frame; 437 flags.bits.no_upd_last = !va_pic->pic_flags.bits.refresh_last; 438 flags.bits.no_upd_gf = !va_pic->pic_flags.bits.refresh_golden_frame; 439 flags.bits.no_upd_arf = !va_pic->pic_flags.bits.refresh_alternate_frame; 440 flags.bits.no_upd_entropy = !va_pic->pic_flags.bits.refresh_entropy_probs; 441 442 pic->pic_flags = flags.value; 443#endif 444 pic->prev_frame_dropped = 0; /* Not yet used */ 445 pic->cpuused = 5; 446 pic->sharpness = va_pic->sharpness_level; 447 pic->num_token_partitions = va_pic->pic_flags.bits.num_token_partitions; /* 2^2 = 4 partitions */ 448 pic->encoded_frame_size = pObj->size & ~31; 449 pic->encoded_frame_base = pObj->buffer_data ;//tobe modified 450 451 { 452 vsp_cmdbuf_reloc_pic_param(&(pic->encoded_frame_base), 453 ctx->pic_param_offset, pObj->psb_buffer, 454 cmdbuf->param_mem_loc, pic); 455 } 456 457 { 458 object_surface_p cur_surf = SURFACE(surface_id); 459 if(!cur_surf) 460 return VA_STATUS_ERROR_UNKNOWN; 461 462 vsp_cmdbuf_reloc_pic_param(&(pic->input_frame.base), 463 ctx->pic_param_offset, &(cur_surf->psb_surface->buf), 464 cmdbuf->param_mem_loc, pic); 465 } 466 467 //vsp_cmdbuf_insert_command(cmdbuf, &cmdbuf->param_mem, 468 // VssVp8encEncodeFrameCommand, 469 // ctx->pic_param_offset, 470 // sizeof(VssVp8encPictureParameterBuffer)); 471 //vsp_cmdbuf_fence_pic_param(cmdbuf, wsbmKBufHandle(wsbmKBuf(cmdbuf->param_mem.drm_buf))); 472 473 do { *cmdbuf->cmd_idx++ = CONTEXT_VP8_ID;\ 474 *cmdbuf->cmd_idx++ = VssVp8encEncodeFrameCommand;\ 475 VSP_RELOC_CMDBUF(cmdbuf->cmd_idx++, ctx->pic_param_offset, &cmdbuf->param_mem);\ 476 *cmdbuf->cmd_idx++ = sizeof(struct VssVp8encPictureParameterBuffer);\ 477 *cmdbuf->cmd_idx++ = 0; *cmdbuf->cmd_idx++ = 0;\ 478 *cmdbuf->cmd_idx++ = wsbmKBufHandle(wsbmKBuf(pObj->psb_buffer->drm_buf)) ; \ 479 *cmdbuf->cmd_idx++ = wsbmKBufHandle(wsbmKBuf((&cmdbuf->param_mem)->drm_buf)); } while(0); 480 481 return vaStatus; 482} 483 484static VAStatus vsp_vp8_process_misc_param(context_VPP_p ctx, object_buffer_p obj_buffer) 485{ 486 VAEncMiscParameterBuffer *pBuffer; 487 VAEncMiscParameterAIR *air_param; 488 VAEncMiscParameterBufferMaxFrameSize *max_frame_size_param; 489 VAEncMiscParameterFrameRate *frame_rate_param; 490 VAEncMiscParameterRateControl *rate_control_param; 491 VAEncMiscParameterHRD *hrd_param; 492 VAStatus vaStatus = VA_STATUS_SUCCESS; 493 ASSERT(obj_buffer->type == VAEncMiscParameterBufferType); 494 pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data; 495 obj_buffer->size = 0; 496 switch (pBuffer->type) { 497 case VAEncMiscParameterTypeFrameRate: 498 frame_rate_param = (VAEncMiscParameterFrameRate *)pBuffer->data; 499 if (frame_rate_param->framerate < 1 || frame_rate_param->framerate > 65535) { 500 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 501 break; 502 } 503 if (ctx->frame_rate == frame_rate_param->framerate) 504 break; 505 drv_debug_msg(VIDEO_DEBUG_GENERAL, "frame rate changed from %d to %d\n", 506 ctx->frame_rate, 507 frame_rate_param->framerate); 508 ctx->frame_rate = frame_rate_param->framerate; 509 ctx->re_send_seq_params = 1 ; 510 break; 511 case VAEncMiscParameterTypeRateControl: 512 rate_control_param = (VAEncMiscParameterRateControl *)pBuffer->data; 513 if (rate_control_param->initial_qp > 63 || 514 rate_control_param->min_qp > 63) { 515 drv_debug_msg(VIDEO_DEBUG_ERROR, "Initial_qp(%d) and min_qpinitial_qp(%d) " 516 "are invalid.\nQP shouldn't be larger than 63 for VP8\n", 517 rate_control_param->initial_qp, rate_control_param->min_qp); 518 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 519 break; 520 } 521 if (rate_control_param->min_qp == ctx->min_qp 522 && rate_control_param->bits_per_second == ctx->bits_per_second) { 523 break; 524 } 525 if (rate_control_param->min_qp != ctx->min_qp) { 526 drv_debug_msg(VIDEO_DEBUG_ERROR, "min_qp was changed from %d to %d\n", 527 ctx->min_qp, rate_control_param->min_qp); 528 ctx->min_qp = rate_control_param->min_qp; 529 } 530 if (rate_control_param->max_qp != ctx->max_qp) { 531 drv_debug_msg(VIDEO_DEBUG_ERROR, "max_qp was changed from %d to %d\n", 532 ctx->max_qp, rate_control_param->max_qp); 533 ctx->max_qp = rate_control_param->max_qp; 534 } 535 if (rate_control_param->initial_qp != ctx->initial_qp) { 536 drv_debug_msg(VIDEO_DEBUG_ERROR, "Initial_qp was changed from %d to %d\n", 537 ctx->initial_qp, rate_control_param->initial_qp); 538 ctx->initial_qp = rate_control_param->initial_qp; 539 } 540 if (rate_control_param->bits_per_second != ctx->bits_per_second) { 541 drv_debug_msg(VIDEO_DEBUG_ERROR, "Initial_qp was changed from %d to %d\n", 542 ctx->bits_per_second, rate_control_param->bits_per_second); 543 ctx->bits_per_second = rate_control_param->bits_per_second; 544 } 545 if (rate_control_param->target_percentage != ctx->rc_undershoot) { 546 drv_debug_msg(VIDEO_DEBUG_ERROR, "rc_undershoot was changed from %d to %d\n", 547 ctx->rc_undershoot, rate_control_param->target_percentage); 548 ctx->rc_undershoot = rate_control_param->target_percentage; 549 } 550 551 ctx->re_send_seq_params = 1 ; 552 break; 553 case VAEncMiscParameterTypeMaxFrameSize: 554 max_frame_size_param = (VAEncMiscParameterBufferMaxFrameSize *)pBuffer->data; 555 if (ctx->max_frame_size == max_frame_size_param->max_frame_size) 556 break; 557 drv_debug_msg(VIDEO_DEBUG_GENERAL, "max frame size changed from %d to %d\n", 558 ctx->max_frame_size, max_frame_size_param->max_frame_size); 559 ctx->max_frame_size = max_frame_size_param->max_frame_size ; 560 ctx->re_send_seq_params = 1 ; 561 break; 562 case VAEncMiscParameterTypeAIR: 563 air_param = (VAEncMiscParameterAIR *)pBuffer->data; 564 if (air_param->air_num_mbs > 65535 || 565 air_param->air_threshold > 65535) { 566 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 567 break; 568 } 569 drv_debug_msg(VIDEO_DEBUG_GENERAL, "air slice size changed to num_air_mbs %d " 570 "air_threshold %d, air_auto %d\n", 571 air_param->air_num_mbs, air_param->air_threshold, 572 air_param->air_auto); 573 ctx->cyclic_intra_refresh = air_param->air_threshold; 574 break; 575 case VAEncMiscParameterTypeHRD: 576 hrd_param = (VAEncMiscParameterHRD *)pBuffer->data; 577 ctx->buffer_size = hrd_param->buffer_size; 578 ctx->initial_buffer_fullness = hrd_param->initial_buffer_fullness; 579 ctx->optimal_buffer_fullness = hrd_param->optimal_buffer_fullness; 580 break; 581 case VAEncMiscParameterTypeQualityLevel: 582 break; 583 default: 584 vaStatus = VA_STATUS_ERROR_UNKNOWN; 585 DEBUG_FAILURE; 586 break; 587 } 588 free(obj_buffer->buffer_data); 589 obj_buffer->buffer_data = NULL; 590 return vaStatus; 591} 592static VAStatus vsp_VP8_RenderPicture( 593 object_context_p obj_context, 594 object_buffer_p *buffers, 595 int num_buffers) 596{ 597 598 int i; 599 psb_driver_data_p driver_data = obj_context->driver_data; 600 INIT_CONTEXT_VPP; 601 VASurfaceID surface_id; 602 VAStatus vaStatus = VA_STATUS_SUCCESS; 603 604 for (i = 0; i < num_buffers; i++) 605 { 606 607 object_buffer_p obj_buffer = buffers[i]; 608 switch (obj_buffer->type) { 609 case VAEncSequenceParameterBufferType: 610 vaStatus = vsp_vp8_process_seqence_param(ctx, obj_buffer); 611 break; 612 case VAEncPictureParameterBufferType: 613 surface_id = obj_context->current_render_surface_id; 614 vaStatus = vsp_vp8_process_picture_param(driver_data,ctx, obj_buffer,surface_id); 615 break; 616 case VAEncMiscParameterBufferType: 617 vaStatus = vsp_vp8_process_misc_param(ctx, obj_buffer); 618 break; 619 default: 620 vaStatus = VA_STATUS_SUCCESS;//VA_STATUS_ERROR_UNKNOWN; 621 DEBUG_FAILURE; 622 } 623 if (vaStatus != VA_STATUS_SUCCESS) { 624 break; 625 } 626 } 627 628 return vaStatus; 629} 630 631static VAStatus vsp_VP8_BeginPicture( 632 object_context_p obj_context) 633{ 634 int ret; 635 VAStatus vaStatus = VA_STATUS_SUCCESS; 636 INIT_CONTEXT_VPP; 637 vsp_cmdbuf_p cmdbuf; 638 639 /* Initialise the command buffer */ 640 ret = vsp_context_get_next_cmdbuf(ctx->obj_context); 641 if (ret) { 642 drv_debug_msg(VIDEO_DEBUG_GENERAL, "get next cmdbuf fail\n"); 643 vaStatus = VA_STATUS_ERROR_UNKNOWN; 644 return vaStatus; 645 } 646 647 cmdbuf = obj_context->vsp_cmdbuf; 648 649 if (ctx->obj_context->frame_count == 0) /* first picture */ 650 { 651 vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VP8_ID, ctx->context_buf, Vss_Sys_STATE_BUF_COMMAND, 652 0, VSP_VP8ENC_STATE_SIZE); 653 } 654 655 /* map param mem */ 656 vaStatus = psb_buffer_map(&cmdbuf->param_mem, &cmdbuf->param_mem_p); 657 if (vaStatus) { 658 return vaStatus; 659 } 660 661 cmdbuf->pic_param_p = cmdbuf->param_mem_p; 662 cmdbuf->seq_param_p = cmdbuf->param_mem_p + ctx->seq_param_offset; 663 cmdbuf->ref_param_p = cmdbuf->param_mem_p + ctx->ref_param_offset; 664 ctx->vp8_seq_cmd_send = 0; 665 ctx->re_send_seq_params = 0; 666 return VA_STATUS_SUCCESS; 667} 668 669static VAStatus vsp_VP8_EndPicture( 670 object_context_p obj_context) 671{ 672 INIT_CONTEXT_VPP; 673 psb_driver_data_p driver_data = obj_context->driver_data; 674 vsp_cmdbuf_p cmdbuf = obj_context->vsp_cmdbuf; 675 676 if(ctx->re_send_seq_params) 677 { 678 vsp_vp8_process_dynamic_seqence_param(ctx); 679 } 680 681 if (cmdbuf->param_mem_p != NULL) { 682 psb_buffer_unmap(&cmdbuf->param_mem); 683 cmdbuf->param_mem_p = NULL; 684 cmdbuf->pic_param_p = NULL; 685 cmdbuf->end_param_p = NULL; 686 cmdbuf->pipeline_param_p = NULL; 687 cmdbuf->denoise_param_p = NULL; 688 cmdbuf->enhancer_param_p = NULL; 689 cmdbuf->sharpen_param_p = NULL; 690 cmdbuf->frc_param_p = NULL; 691 cmdbuf->ref_param_p = NULL; 692 } 693 694// ctx->obj_context->frame_count++; 695 696 697 if (vsp_context_flush_cmdbuf(ctx->obj_context)) 698 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_VPP: flush deblock cmdbuf error\n"); 699 700 return VA_STATUS_SUCCESS; 701} 702 703struct format_vtable_s vsp_VP8_vtable = { 704queryConfigAttributes: 705 vsp_VP8_QueryConfigAttributes, 706validateConfig: 707 vsp_VP8_ValidateConfig, 708createContext: 709 vsp_VP8_CreateContext, 710destroyContext: 711 vsp_VP8_DestroyContext, 712beginPicture: 713 vsp_VP8_BeginPicture, 714renderPicture: 715 vsp_VP8_RenderPicture, 716endPicture: 717 vsp_VP8_EndPicture 718}; 719 720