1 /* 2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved. 3 * Copyright (c) Imagination Technologies Limited, UK 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 /* 27 * Authors: 28 * Li Zeng <li.zeng (at) intel.com> 29 */ 30 #include "tng_vld_dec.h" 31 #include "psb_drv_debug.h" 32 #include "hwdefs/dxva_fw_ctrl.h" 33 #include "hwdefs/reg_io2.h" 34 #include "hwdefs/msvdx_offsets.h" 35 #include "hwdefs/msvdx_cmds_io2.h" 36 #include "va/va_dec_jpeg.h" 37 #include "va/va_dec_vp8.h" 38 39 #include <malloc.h> 40 41 #define GET_SURFACE_INFO_colocated_index(psb_surface) ((int) (psb_surface->extra_info[3])) 42 #define SET_SURFACE_INFO_colocated_index(psb_surface, val) psb_surface->extra_info[3] = (uint32_t) val; 43 44 /* Set MSVDX Front end register */ 45 void vld_dec_FE_state(object_context_p obj_context, psb_buffer_p buf) 46 { 47 psb_cmdbuf_p cmdbuf = obj_context->cmdbuf; 48 context_DEC_p ctx = (context_DEC_p) obj_context->format_data; 49 CTRL_ALLOC_HEADER *cmd_header = (CTRL_ALLOC_HEADER *)psb_cmdbuf_alloc_space(cmdbuf, sizeof(CTRL_ALLOC_HEADER)); 50 51 cmd_header->ui32Cmd_AdditionalParams = CMD_CTRL_ALLOC_HEADER; 52 cmd_header->ui32ExternStateBuffAddr = 0; 53 if (buf) 54 RELOC(cmd_header->ui32ExternStateBuffAddr, 0, buf); 55 cmd_header->ui32MacroblockParamAddr = 0; /* Only EC needs to set this */ 56 57 ctx->cmd_params = &cmd_header->ui32Cmd_AdditionalParams; 58 ctx->p_slice_params = &cmd_header->ui32SliceParams; 59 cmd_header->ui32SliceParams = 0; 60 61 ctx->slice_first_pic_last = &cmd_header->uiSliceFirstMbYX_uiPicLastMbYX; 62 *ctx->slice_first_pic_last = 0; 63 64 ctx->p_range_mapping_base0 = &cmd_header->ui32AltOutputAddr[0]; 65 ctx->p_range_mapping_base1 = &cmd_header->ui32AltOutputAddr[1]; 66 67 ctx->alt_output_flags = &cmd_header->ui32AltOutputFlags; 68 69 cmd_header->ui32AltOutputFlags = 0; 70 cmd_header->ui32AltOutputAddr[0] = 0; 71 cmd_header->ui32AltOutputAddr[1] = 0; 72 } 73 74 /* Programme the Alt output if there is a rotation*/ 75 void vld_dec_setup_alternative_frame(object_context_p obj_context) 76 { 77 uint32_t cmd = 0; 78 psb_cmdbuf_p cmdbuf = obj_context->cmdbuf; 79 context_DEC_p ctx = (context_DEC_p) obj_context->format_data; 80 psb_surface_p src_surface = obj_context->current_render_target->psb_surface; 81 psb_surface_p out_loop_surface = obj_context->current_render_target->out_loop_surface; 82 int ved_scaling = (CONTEXT_SCALING(obj_context) && !ctx->yuv_ctx); 83 uint32_t startX = 0, startY = 0, luma_addr_offset = 0, chroma_addr_offset = 0; 84 85 /* In VPP ctx, current_render_target is rotated surface */ 86 if (ctx->yuv_ctx && (VAEntrypointVideoProc == obj_context->entry_point)) { 87 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Setup second-pass rotation\n"); 88 out_loop_surface = src_surface; 89 src_surface = ctx->yuv_ctx->src_surface; 90 } 91 92 if (CONTEXT_ALTERNATIVE_OUTPUT(obj_context) || obj_context->entry_point == VAEntrypointVideoProc) { 93 if (ved_scaling) { 94 out_loop_surface = obj_context->current_render_target->scaling_surface; 95 #ifndef BAYTRAIL 96 tng_ved_write_scale_reg(obj_context); 97 98 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION, SCALE_INPUT_SIZE_SEL, 1); 99 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION, SCALE_ENABLE, 1); 100 #endif 101 } else { 102 startX = ((uint32_t)obj_context->current_render_target->offset_x_s + 0x3f) & ~0x3f; 103 startY = ((uint32_t)obj_context->current_render_target->offset_y_s + 0x1) & ~0x1; 104 luma_addr_offset = (((uint32_t)(startX + out_loop_surface->stride * startY)) + 0x3f ) & ~0x3f; 105 chroma_addr_offset = (((uint32_t)(startX + out_loop_surface->stride * startY / 2)) + 0x3f ) & ~0x3f; 106 } 107 108 if (out_loop_surface == NULL) { 109 drv_debug_msg(VIDEO_DEBUG_ERROR, "out-loop surface is NULL, abort msvdx alternative output\n"); 110 return; 111 } 112 113 if (GET_SURFACE_INFO_rotate(out_loop_surface) != obj_context->msvdx_rotate && !ved_scaling) 114 drv_debug_msg(VIDEO_DEBUG_WARNING, "Display rotate mode does not match surface rotate mode!\n"); 115 116 /* CRendecBlock RendecBlk( mCtrlAlloc , RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); */ 117 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS)); 118 119 psb_cmdbuf_rendec_write_address(cmdbuf, &out_loop_surface->buf, out_loop_surface->buf.buffer_ofs + luma_addr_offset); 120 psb_cmdbuf_rendec_write_address(cmdbuf, &out_loop_surface->buf, out_loop_surface->buf.buffer_ofs + chroma_addr_offset + out_loop_surface->chroma_offset); 121 122 psb_cmdbuf_rendec_end(cmdbuf); 123 124 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ALT_PICTURE_ENABLE, 1); 125 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_ROW_STRIDE, out_loop_surface->stride_mode); 126 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */ 127 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_MODE, GET_SURFACE_INFO_rotate(out_loop_surface)); 128 129 RELOC(*ctx->p_range_mapping_base0, out_loop_surface->buf.buffer_ofs + luma_addr_offset, &out_loop_surface->buf); 130 RELOC(*ctx->p_range_mapping_base1, out_loop_surface->buf.buffer_ofs + chroma_addr_offset + out_loop_surface->chroma_offset, &out_loop_surface->buf); 131 } 132 133 if (obj_context->profile == VAProfileVP8Version0_3 || 134 obj_context->profile == VAProfileJPEGBaseline || ctx->yuv_ctx) { 135 psb_cmdbuf_rendec_start(cmdbuf, (REG_MSVDX_CMD_OFFSET + MSVDX_CMDS_AUX_LINE_BUFFER_BASE_ADDRESS_OFFSET)); 136 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->aux_line_buffer_vld, ctx->aux_line_buffer_vld.buffer_ofs); 137 psb_cmdbuf_rendec_end(cmdbuf); 138 139 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION, USE_AUX_LINE_BUF, 1); 140 if (ctx->yuv_ctx) 141 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , RECON_WRITE_DISABLE, 1); 142 } 143 144 /* Set the rotation registers */ 145 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION)); 146 psb_cmdbuf_rendec_write(cmdbuf, cmd); 147 *ctx->alt_output_flags = cmd; 148 149 cmd = 0; 150 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, EXTENDED_ROW_STRIDE, EXT_ROW_STRIDE, src_surface->stride / 64); 151 psb_cmdbuf_rendec_write(cmdbuf, cmd); 152 153 psb_cmdbuf_rendec_end(cmdbuf); 154 } 155 156 int vld_dec_slice_parameter_size(object_context_p obj_context) 157 { 158 int size; 159 160 switch (obj_context->profile) { 161 case VAProfileMPEG2Simple: 162 case VAProfileMPEG2Main: 163 size = sizeof(VASliceParameterBufferMPEG2); 164 break; 165 case VAProfileMPEG4Simple: 166 case VAProfileMPEG4AdvancedSimple: 167 case VAProfileMPEG4Main: 168 case VAProfileH263Baseline: 169 size = sizeof(VASliceParameterBufferMPEG4); 170 break; 171 case VAProfileH264Baseline: 172 case VAProfileH264Main: 173 case VAProfileH264High: 174 case VAProfileH264ConstrainedBaseline: 175 size = sizeof(VASliceParameterBufferH264); 176 break; 177 case VAProfileVC1Simple: 178 case VAProfileVC1Main: 179 case VAProfileVC1Advanced: 180 size = sizeof(VASliceParameterBufferVC1); 181 break; 182 case VAProfileVP8Version0_3: 183 size = sizeof(VASliceParameterBufferVP8); 184 case VAProfileJPEGBaseline: 185 size = sizeof(VASliceParameterBufferJPEGBaseline); 186 default: 187 size = 0; 188 break; 189 } 190 191 return size; 192 } 193 194 VAStatus vld_dec_process_slice_data(context_DEC_p ctx, object_buffer_p obj_buffer) 195 { 196 VAStatus vaStatus = VA_STATUS_SUCCESS; 197 void *slice_param; 198 int buffer_idx = 0; 199 unsigned int element_idx = 0, element_size; 200 201 ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType)); 202 203 ASSERT(ctx->pic_params); 204 ASSERT(ctx->slice_param_list_idx); 205 206 #if 0 207 if (!ctx->pic_params) { 208 /* Picture params missing */ 209 return VA_STATUS_ERROR_UNKNOWN; 210 } 211 #endif 212 if ((NULL == obj_buffer->psb_buffer) || 213 (0 == obj_buffer->size)) { 214 /* We need to have data in the bitstream buffer */ 215 return VA_STATUS_ERROR_UNKNOWN; 216 } 217 218 element_size = vld_dec_slice_parameter_size(ctx->obj_context); 219 220 while (buffer_idx < ctx->slice_param_list_idx) { 221 object_buffer_p slice_buf = ctx->slice_param_list[buffer_idx]; 222 if (element_idx >= slice_buf->num_elements) { 223 /* Move to next buffer */ 224 element_idx = 0; 225 buffer_idx++; 226 continue; 227 } 228 229 slice_param = slice_buf->buffer_data; 230 slice_param = (void *)((unsigned long)slice_param + element_idx * element_size); 231 element_idx++; 232 vaStatus = vld_dec_process_slice(ctx, slice_param, obj_buffer); 233 if (vaStatus != VA_STATUS_SUCCESS) { 234 DEBUG_FAILURE; 235 break; 236 } 237 } 238 ctx->slice_param_list_idx = 0; 239 240 return vaStatus; 241 } 242 /* 243 * Adds a VASliceParameterBuffer to the list of slice params 244 */ 245 VAStatus vld_dec_add_slice_param(context_DEC_p ctx, object_buffer_p obj_buffer) 246 { 247 ASSERT(obj_buffer->type == VASliceParameterBufferType); 248 if (ctx->slice_param_list_idx >= ctx->slice_param_list_size) { 249 unsigned char *new_list; 250 ctx->slice_param_list_size += 8; 251 new_list = realloc(ctx->slice_param_list, 252 sizeof(object_buffer_p) * ctx->slice_param_list_size); 253 if (NULL == new_list) { 254 return VA_STATUS_ERROR_ALLOCATION_FAILED; 255 } 256 ctx->slice_param_list = (object_buffer_p*) new_list; 257 } 258 ctx->slice_param_list[ctx->slice_param_list_idx] = obj_buffer; 259 ctx->slice_param_list_idx++; 260 return VA_STATUS_SUCCESS; 261 } 262 263 void vld_dec_write_kick(object_context_p obj_context) 264 { 265 psb_cmdbuf_p cmdbuf = obj_context->cmdbuf; 266 *cmdbuf->cmd_idx++ = CMD_COMPLETION; 267 } 268 269 VAStatus vld_dec_process_slice(context_DEC_p ctx, 270 void *vld_slice_param, 271 object_buffer_p obj_buffer) 272 { 273 VAStatus vaStatus = VA_STATUS_SUCCESS; 274 VASliceParameterBufferBase *slice_param = (VASliceParameterBufferBase *) vld_slice_param; 275 276 ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType)); 277 278 if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) || 279 (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL)) { 280 #ifndef SLICE_HEADER_PARSING 281 if (0 == slice_param->slice_data_size) { 282 vaStatus = VA_STATUS_ERROR_UNKNOWN; 283 DEBUG_FAILURE; 284 return vaStatus; 285 } 286 #endif 287 ASSERT(!ctx->split_buffer_pending); 288 289 if (psb_context_get_next_cmdbuf(ctx->obj_context)) { 290 vaStatus = VA_STATUS_ERROR_UNKNOWN; 291 DEBUG_FAILURE; 292 return vaStatus; 293 } 294 vld_dec_FE_state(ctx->obj_context, ctx->preload_buffer); 295 ctx->begin_slice(ctx, slice_param); 296 ctx->slice_data_buffer = obj_buffer->psb_buffer; 297 #ifdef SLICE_HEADER_PARSING 298 if (ctx->parse_enabled == 1) 299 psb_cmdbuf_dma_write_key(ctx->obj_context->cmdbuf, 300 ctx->SR_flags, 301 ctx->parse_key); 302 else 303 #endif 304 psb_cmdbuf_dma_write_bitstream(ctx->obj_context->cmdbuf, 305 obj_buffer->psb_buffer, 306 obj_buffer->psb_buffer->buffer_ofs + slice_param->slice_data_offset, 307 slice_param->slice_data_size, 308 ctx->bits_offset, 309 ctx->SR_flags); 310 311 if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) { 312 ctx->split_buffer_pending = TRUE; 313 } 314 } else { 315 ASSERT(ctx->split_buffer_pending); 316 ASSERT(0 == slice_param->slice_data_offset); 317 if (slice_param->slice_data_size) { 318 psb_cmdbuf_dma_write_bitstream_chained(ctx->obj_context->cmdbuf, 319 obj_buffer->psb_buffer, 320 slice_param->slice_data_size); 321 } 322 } 323 324 if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL) || 325 (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END)) { 326 if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END) { 327 ASSERT(ctx->split_buffer_pending); 328 } 329 330 ctx->process_slice(ctx, slice_param); 331 vld_dec_write_kick(ctx->obj_context); 332 333 ctx->split_buffer_pending = FALSE; 334 ctx->obj_context->video_op = psb_video_vld; 335 ctx->obj_context->flags = 0; 336 337 ctx->end_slice(ctx); 338 339 if (psb_context_submit_cmdbuf(ctx->obj_context)) { 340 vaStatus = VA_STATUS_ERROR_UNKNOWN; 341 } 342 } 343 return vaStatus; 344 } 345 346 VAStatus vld_dec_allocate_colocated_buffer(context_DEC_p ctx, object_surface_p obj_surface, uint32_t size) 347 { 348 psb_buffer_p buf; 349 VAStatus vaStatus; 350 psb_surface_p surface = obj_surface->psb_surface; 351 int index = GET_SURFACE_INFO_colocated_index(surface); 352 353 if (!index) { 354 index = ctx->colocated_buffers_idx; 355 if (index >= ctx->colocated_buffers_size) { 356 return VA_STATUS_ERROR_UNKNOWN; 357 } 358 359 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocating colocated buffer for surface %08x size = %08x\n", surface, size); 360 361 buf = &(ctx->colocated_buffers[index]); 362 vaStatus = psb_buffer_create(ctx->obj_context->driver_data, size, psb_bt_vpu_only, buf); 363 if (VA_STATUS_SUCCESS != vaStatus) { 364 return vaStatus; 365 } 366 ctx->colocated_buffers_idx++; 367 SET_SURFACE_INFO_colocated_index(surface, index + 1); /* 0 means unset, index is offset by 1 */ 368 } else { 369 buf = &(ctx->colocated_buffers[index - 1]); 370 if (buf->size < size) { 371 psb_buffer_destroy(buf); 372 vaStatus = psb_buffer_create(ctx->obj_context->driver_data, size, psb_bt_vpu_only, buf); 373 if (VA_STATUS_SUCCESS != vaStatus) { 374 return vaStatus; 375 } 376 SET_SURFACE_INFO_colocated_index(surface, index); /* replace the original buffer */ 377 } 378 } 379 return VA_STATUS_SUCCESS; 380 } 381 382 psb_buffer_p vld_dec_lookup_colocated_buffer(context_DEC_p ctx, psb_surface_p surface) 383 { 384 int index = GET_SURFACE_INFO_colocated_index(surface); 385 if (!index) { 386 return NULL; 387 } 388 return &(ctx->colocated_buffers[index-1]); /* 0 means unset, index is offset by 1 */ 389 } 390 391 VAStatus vld_dec_CreateContext(context_DEC_p ctx, object_context_p obj_context) 392 { 393 VAStatus vaStatus = VA_STATUS_SUCCESS; 394 395 ctx->obj_context = obj_context; 396 ctx->split_buffer_pending = FALSE; 397 ctx->slice_param_list_size = 8; 398 ctx->slice_param_list = (object_buffer_p*) calloc(1, sizeof(object_buffer_p) * ctx->slice_param_list_size); 399 ctx->slice_param_list_idx = 0; 400 401 if (NULL == ctx->slice_param_list) { 402 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 403 DEBUG_FAILURE; 404 return vaStatus; 405 } 406 407 ctx->colocated_buffers_size = obj_context->num_render_targets; 408 ctx->colocated_buffers_idx = 0; 409 ctx->colocated_buffers = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s) * ctx->colocated_buffers_size); 410 if (NULL == ctx->colocated_buffers) { 411 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 412 DEBUG_FAILURE; 413 free(ctx->slice_param_list); 414 } 415 416 if (vaStatus == VA_STATUS_SUCCESS) { 417 vaStatus = psb_buffer_create(obj_context->driver_data, 418 AUX_LINE_BUFFER_VLD_SIZE, 419 psb_bt_cpu_vpu, 420 &ctx->aux_line_buffer_vld); 421 DEBUG_FAILURE; 422 } 423 424 return vaStatus; 425 } 426 427 void vld_dec_DestroyContext(context_DEC_p ctx) 428 { 429 int i; 430 ctx->preload_buffer = NULL; 431 432 psb_buffer_destroy(&ctx->aux_line_buffer_vld); 433 434 if (ctx->slice_param_list) { 435 free(ctx->slice_param_list); 436 ctx->slice_param_list = NULL; 437 } 438 439 if (ctx->colocated_buffers) { 440 for (i = 0; i < ctx->colocated_buffers_idx; ++i) 441 psb_buffer_destroy(&(ctx->colocated_buffers[i])); 442 443 free(ctx->colocated_buffers); 444 ctx->colocated_buffers = NULL; 445 } 446 } 447 448 VAStatus vld_dec_RenderPicture( 449 object_context_p obj_context, 450 object_buffer_p *buffers, 451 int num_buffers) 452 { 453 int i; 454 context_DEC_p ctx = (context_DEC_p) obj_context->format_data; 455 VAStatus vaStatus = VA_STATUS_SUCCESS; 456 457 for (i = 0; i < num_buffers; i++) { 458 object_buffer_p obj_buffer = buffers[i]; 459 psb__dump_va_buffers_verbose(obj_buffer); 460 461 switch (obj_buffer->type) { 462 case VASliceParameterBufferType: 463 vaStatus = vld_dec_add_slice_param(ctx, obj_buffer); 464 DEBUG_FAILURE; 465 break; 466 467 case VASliceDataBufferType: 468 case VAProtectedSliceDataBufferType: 469 vaStatus = vld_dec_process_slice_data(ctx, obj_buffer); 470 DEBUG_FAILURE; 471 break; 472 473 default: 474 vaStatus = ctx->process_buffer(ctx, obj_buffer); 475 DEBUG_FAILURE; 476 } 477 if (vaStatus != VA_STATUS_SUCCESS) { 478 break; 479 } 480 } 481 482 return vaStatus; 483 } 484 485 void vld_dec_yuv_rotate(object_context_p obj_context) 486 { 487 VAStatus vaStatus = VA_STATUS_SUCCESS; 488 struct format_vtable_s *vtable = &tng_yuv_processor_vtable; 489 struct surface_param_s surface_param; 490 struct object_buffer_s buffer; 491 object_buffer_p buffer_p = &buffer; 492 493 surface_param.src_surface = obj_context->current_render_target->scaling_surface; 494 surface_param.display_width = obj_context->current_render_target->buffer_width_s; 495 surface_param.display_height = obj_context->current_render_target->buffer_height_s; 496 surface_param.coded_width = obj_context->current_render_target->width_s; 497 surface_param.coded_height = obj_context->current_render_target->height_s; 498 499 buffer.num_elements = 1; 500 buffer.type = YUVProcessorSurfaceType; 501 buffer.size = sizeof(struct surface_param_s); 502 buffer.buffer_data = (unsigned char *)&surface_param; 503 504 vtable->createContext(obj_context, NULL); 505 vtable->beginPicture(obj_context); 506 vtable->renderPicture(obj_context, &buffer_p, 1); 507 vtable->endPicture(obj_context); 508 vtable->destroyContext(obj_context); 509 } 510