uint32_t psbWsbmGetKBufHandle(void *buf) { if (!buf) { ETRACE("invalid ttm buffer"); return 0; } return (wsbmKBufHandle(wsbmKBuf((struct _WsbmBufferObject *)buf))); }
/* * Create and attach a rotate surface to obj_surface */ VAStatus psb_CreateRotateSurface( object_context_p obj_context, object_surface_p obj_surface, int msvdx_rotate ) { int width, height; psb_surface_p rotate_surface = NULL; bool rotate_surfaceAlloc = false; VAStatus vaStatus = VA_STATUS_SUCCESS; int need_realloc = 0; unsigned int flags = 0; psb_surface_share_info_p share_info = obj_surface->share_info; psb_driver_data_p driver_data = obj_context->driver_data; int rotate_stride = 0, rotate_tiling = 0; object_config_p obj_config = CONFIG(obj_context->config_id); unsigned char * surface_data; CHECK_CONFIG(obj_config); rotate_surface = obj_surface->out_loop_surface; if (msvdx_rotate == 0 #ifdef OVERLAY_ENABLE_MIRROR /*Bypass 180 degree rotate when overlay enabling mirror*/ || msvdx_rotate == VA_ROTATION_180 #endif ) return vaStatus; if (rotate_surface) { CHECK_SURFACE_REALLOC(rotate_surface, msvdx_rotate, need_realloc); if (need_realloc == 0) { goto exit; } else { /* free the old rotate surface */ /*FIX ME: it is not safe to do that because surfaces may be in use for rendering.*/ psb_surface_destroy(obj_surface->out_loop_surface); memset(rotate_surface, 0, sizeof(*rotate_surface)); } } else { rotate_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); CHECK_ALLOCATION(rotate_surface); rotate_surfaceAlloc = true; } #ifdef PSBVIDEO_MSVDX_DEC_TILING SET_SURFACE_INFO_tiling(rotate_surface, GET_SURFACE_INFO_tiling(obj_surface->psb_surface)); #endif #ifdef PSBVIDEO_MRFL_VPP_ROTATE SET_SURFACE_INFO_rotate(rotate_surface, msvdx_rotate); #endif drv_debug_msg(VIDEO_DEBUG_GENERAL, "Try to allocate surface for alternative rotate output\n"); flags = IS_ROTATED; if (msvdx_rotate == 2 /* VA_ROTATION_180 */) { width = obj_surface->width; height = obj_surface->height; #ifdef PSBVIDEO_MRFL_VPP_ROTATE if (obj_config->entrypoint == VAEntrypointVideoProc && share_info && share_info->out_loop_khandle) { vaStatus = psb_surface_create_from_kbuf(driver_data, width, height, obj_surface->psb_surface->size, VA_FOURCC_NV12, share_info->out_loop_khandle, obj_surface->psb_surface->stride, obj_surface->psb_surface->stride, obj_surface->psb_surface->stride, 0, 0, 0, rotate_surface); } else #endif vaStatus = psb_surface_create(driver_data, width, height, VA_FOURCC_NV12, flags, rotate_surface); } else { width = obj_surface->height_origin; height = (obj_surface->width + 0x1f) & ~0x1f; #ifdef PSBVIDEO_MRFL_VPP_ROTATE if (obj_config->entrypoint == VAEntrypointVideoProc && share_info && share_info->out_loop_khandle != 0) { drv_debug_msg(VIDEO_DEBUG_GENERAL,"Create the surface from kbuf out_loop_khandle=%x!\n", share_info->out_loop_khandle); rotate_tiling = GET_SURFACE_INFO_tiling(rotate_surface); rotate_stride = get_surface_stride(width, rotate_tiling); vaStatus = psb_surface_create_from_kbuf(driver_data, width, height, (rotate_stride * height * 3) / 2, VA_FOURCC_NV12, share_info->out_loop_khandle, rotate_stride, rotate_stride, rotate_stride, 0, rotate_stride * height, rotate_stride * height, rotate_surface); } else #endif { drv_debug_msg(VIDEO_DEBUG_GENERAL,"Create rotated buffer. width=%d, height=%d\n", width, height); if (CONTEXT_SCALING(obj_context)) { width = obj_context->scaling_buffer_height; height = (obj_context->scaling_buffer_width+ 0x1f) & ~0x1f; } vaStatus = psb_surface_create(driver_data, width, height, VA_FOURCC_NV12, flags, rotate_surface); } } if (VA_STATUS_SUCCESS != vaStatus) { free(rotate_surface); obj_surface->out_loop_surface = NULL; vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; DEBUG_FAILURE; return vaStatus; } //clear rotation surface if (CONTEXT_SCALING(obj_context)) { if (psb_buffer_map(&rotate_surface->buf, &surface_data)) { drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to map rotation buffer before clear it"); } else { memset(surface_data, 0, rotate_surface->chroma_offset); memset(surface_data + rotate_surface->chroma_offset, 0x80, rotate_surface->size - rotate_surface->chroma_offset); psb_buffer_unmap(&rotate_surface->buf); } } obj_surface->width_r = width; obj_surface->height_r = height; #ifdef PSBVIDEO_MSVDX_DEC_TILING drv_debug_msg(VIDEO_DEBUG_GENERAL, "attempt to update tile context\n"); if (GET_SURFACE_INFO_tiling(rotate_surface) && obj_config->entrypoint != VAEntrypointVideoProc) { drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context\n"); object_context_p obj_context = CONTEXT(obj_surface->context_id); if (NULL == obj_context) { vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; DEBUG_FAILURE; if (rotate_surface != NULL && rotate_surfaceAlloc) { free(rotate_surface); rotate_surface = NULL; } return vaStatus; } unsigned long msvdx_tile = psb__tile_stride_log2_256(obj_surface->width_r); obj_context->msvdx_tile &= 0xf; /* clear rotate tile */ obj_context->msvdx_tile |= (msvdx_tile << 4); obj_context->ctp_type &= (~PSB_CTX_TILING_MASK); /* clear tile context */ obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16); psb_update_context(driver_data, obj_context->ctp_type); } #endif exit: obj_surface->out_loop_surface = rotate_surface; SET_SURFACE_INFO_rotate(rotate_surface, msvdx_rotate); /* derive the protected flag from the primay surface */ SET_SURFACE_INFO_protect(rotate_surface, GET_SURFACE_INFO_protect(obj_surface->psb_surface)); /*notify hwc that rotated buffer is ready to use. * TODO: Do these in psb_SyncSurface() */ if (share_info != NULL) { share_info->width_r = rotate_surface->stride; share_info->height_r = obj_surface->height_r; share_info->out_loop_khandle = (uint32_t)(wsbmKBufHandle(wsbmKBuf(rotate_surface->buf.drm_buf))); share_info->metadata_rotate = VAROTATION2HAL(driver_data->va_rotate); share_info->surface_rotate = VAROTATION2HAL(msvdx_rotate); share_info->out_loop_luma_stride = rotate_surface->stride; share_info->out_loop_chroma_u_stride = rotate_surface->stride; share_info->out_loop_chroma_v_stride = rotate_surface->stride; } return vaStatus; }
VAStatus psb_CreateScalingSurface( object_context_p obj_context, object_surface_p obj_surface ) { psb_surface_p psb_surface; VAStatus vaStatus = VA_STATUS_SUCCESS; psb_surface_share_info_p share_info = obj_surface->share_info; unsigned int set_flags, clear_flags; int ret = 0; if (obj_context->driver_data->render_rect.width <= obj_context->scaling_width || obj_context->driver_data->render_rect.height <= obj_context->scaling_height) { drv_debug_msg(VIDEO_DEBUG_GENERAL, "Either downscaling is not required or upscaling is needed for the target resolution\n"); obj_context->msvdx_scaling = 0; /* Disable downscaling */ clearScalingInfo(share_info); return VA_STATUS_ERROR_OPERATION_FAILED; } psb_surface = obj_surface->scaling_surface; /* Check if downscaling resolution has been changed */ if (psb_surface) { if (obj_surface->width_s != obj_context->scaling_width || obj_surface->height_s != obj_context->scaling_height) { psb_surface_destroy(psb_surface); free(psb_surface); psb_surface = NULL; drv_debug_msg(VIDEO_DEBUG_GENERAL, "downscaling buffer realloc: %d x %d -> %d x %d\n", obj_surface->width_s, obj_surface->height_s, obj_context->scaling_width, obj_context->scaling_height); clearScalingInfo(share_info); } } if (!psb_surface) { drv_debug_msg(VIDEO_DEBUG_GENERAL, "Try to allocate surface for alternative scaling output: %dx%d\n", obj_context->scaling_width, obj_context->scaling_height); psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); CHECK_ALLOCATION(psb_surface); vaStatus = psb_surface_create(obj_context->driver_data, obj_context->scaling_width, (obj_context->scaling_height + 0x1f) & ~0x1f, VA_FOURCC_NV12, 0, psb_surface); //set_flags = WSBM_PL_FLAG_CACHED | DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_SHARED; //clear_flags = WSBM_PL_FLAG_UNCACHED | WSBM_PL_FLAG_WC; //ret = psb_buffer_setstatus(&psb_surface->buf, set_flags, clear_flags); if (VA_STATUS_SUCCESS != vaStatus || ret) { drv_debug_msg(VIDEO_DEBUG_GENERAL, "allocate scaling buffer fail\n"); free(psb_surface); obj_surface->scaling_surface = NULL; vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; DEBUG_FAILURE; return vaStatus; } obj_surface->width_s = obj_context->scaling_width; obj_surface->height_s = obj_context->scaling_height; obj_surface->buffer_width_s = obj_context->scaling_width; obj_surface->buffer_height_s = obj_context->scaling_height; obj_surface->offset_x_s= obj_context->scaling_offset_x; obj_surface->offset_y_s= obj_context->scaling_offset_y; obj_context->scaling_update = 1; } obj_surface->scaling_surface = psb_surface; /* derive the protected flag from the primay surface */ SET_SURFACE_INFO_protect(psb_surface, GET_SURFACE_INFO_protect(obj_surface->psb_surface)); /*notify hwc that rotated buffer is ready to use. * TODO: Do these in psb_SyncSurface() */ if (share_info != NULL) { share_info->width_s = obj_surface->width_s; share_info->height_s = obj_surface->height_s; share_info->scaling_khandle = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf))); share_info->scaling_luma_stride = psb_surface->stride; share_info->scaling_chroma_u_stride = psb_surface->stride; share_info->scaling_chroma_v_stride = psb_surface->stride; } return vaStatus; }
static VAStatus vsp_vp8_process_picture_param( psb_driver_data_p driver_data, context_VPP_p ctx, object_buffer_p obj_buffer, VASurfaceID surface_id) { VAStatus vaStatus = VA_STATUS_SUCCESS; vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf; VAEncPictureParameterBufferVP8 *va_pic = (VAEncPictureParameterBufferVP8 *) obj_buffer->buffer_data; struct VssVp8encPictureParameterBuffer *pic = (struct VssVp8encPictureParameterBuffer *)cmdbuf->pic_param_p; struct VssVp8encSequenceParameterBuffer *seq = (struct VssVp8encSequenceParameterBuffer *)cmdbuf->seq_param_p; int ref_frame_width, ref_frame_height; vp8_fw_pic_flags flags; ref_frame_width = (ctx->vp8_seq_param.frame_width + 2 * 32 + 63) & (~63); ref_frame_height = (ctx->vp8_seq_param.frame_height + 2 * 32 + 63) & (~63); //map parameters object_buffer_p pObj = BUFFER(va_pic->coded_buf); //tobe modified if (!pObj) return VA_STATUS_ERROR_UNKNOWN; object_surface_p src_surface = SURFACE(surface_id); pic->input_frame.surface_id = surface_id; pic->input_frame.irq = 1; pic->input_frame.height = ctx->vp8_seq_param.frame_height; pic->input_frame.width = ctx->vp8_seq_param.frame_width; /* NOTE: In VIED API doc, stride must be the nearest integer multiple of 32 */ /* use vaCreateSurfaceWithAttribute with VAExternalMemoryNULL to create surface*/ //pic->input_frame.stride = (ctx->frame_width + 31) & (~31); pic->input_frame.stride = ctx->obj_context->current_render_target->psb_surface->stride; pic->input_frame.format = 0; /* TODO: Specify NV12 = 0 */ pic->recon_frame.irq = 0; pic->recon_frame.width = ref_frame_width; pic->recon_frame.height = ref_frame_height; pic->version = 0; flags.value = 0; flags.bits.force_kf = va_pic->ref_flags.bits.force_kf; flags.bits.no_ref_last = va_pic->ref_flags.bits.no_ref_last; flags.bits.no_ref_gf = va_pic->ref_flags.bits.no_ref_gf; flags.bits.no_ref_arf = va_pic->ref_flags.bits.no_ref_arf; flags.bits.upd_last = va_pic->pic_flags.bits.refresh_last; flags.bits.upd_gf = va_pic->pic_flags.bits.copy_buffer_to_golden; flags.bits.upd_arf = va_pic->pic_flags.bits.copy_buffer_to_alternate; flags.bits.no_upd_last = !va_pic->pic_flags.bits.refresh_last; flags.bits.no_upd_gf = !va_pic->pic_flags.bits.refresh_golden_frame; flags.bits.no_upd_arf = !va_pic->pic_flags.bits.refresh_alternate_frame; flags.bits.upd_entropy = va_pic->pic_flags.bits.refresh_entropy_probs; if (ctx->temporal_layer_number > 1) flags.bits.upd_entropy = 0; pic->pic_flags = flags.value; pic->prev_frame_dropped = 0; /* Not yet used */ pic->cpuused = 5; pic->sharpness = va_pic->sharpness_level; pic->num_token_partitions = va_pic->pic_flags.bits.num_token_partitions; /* 2^2 = 4 partitions */ pic->encoded_frame_size = pObj->size & ~31; pic->encoded_frame_base = (uint32_t)pObj->buffer_data; { vsp_cmdbuf_reloc_pic_param(&(pic->encoded_frame_base), ctx->pic_param_offset, pObj->psb_buffer, cmdbuf->param_mem_loc, pic); } { object_surface_p cur_surf = SURFACE(surface_id); if (!cur_surf) return VA_STATUS_ERROR_UNKNOWN; vsp_cmdbuf_reloc_pic_param(&(pic->input_frame.base), 0, &(cur_surf->psb_surface->buf), cmdbuf->param_mem_loc, pic); vsp_cmdbuf_reloc_pic_param(&(pic->input_frame.base_uv), pic->input_frame.stride * ctx->obj_context->current_render_target->height, &(cur_surf->psb_surface->buf), cmdbuf->param_mem_loc, pic); } *cmdbuf->cmd_idx++ = CONTEXT_VP8_ID; *cmdbuf->cmd_idx++ = VssVp8encEncodeFrameCommand; VSP_RELOC_CMDBUF(cmdbuf->cmd_idx++, ctx->pic_param_offset, &cmdbuf->param_mem); *cmdbuf->cmd_idx++ = sizeof(struct VssVp8encPictureParameterBuffer); *cmdbuf->cmd_idx++ = 0; *cmdbuf->cmd_idx++ = 0; *cmdbuf->cmd_idx++ = wsbmKBufHandle(wsbmKBuf(pObj->psb_buffer->drm_buf)) ; *cmdbuf->cmd_idx++ = wsbmKBufHandle(wsbmKBuf((&cmdbuf->param_mem)->drm_buf)); return vaStatus; }