/* * 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; }
static VAStatus tng__yuv_processor_execute(context_DEC_p dec_ctx, object_buffer_p obj_buffer) { /* psb_surface_p target_surface = dec_ctx->obj_context->current_render_target->psb_surface; */ context_yuv_processor_p ctx = dec_ctx->yuv_ctx; uint32_t reg_value; VAStatus vaStatus; ASSERT(obj_buffer->type == YUVProcessorSurfaceType || obj_buffer->type == VAProcPipelineParameterBufferType); ASSERT(obj_buffer->num_elements == 1); ASSERT(obj_buffer->size == sizeof(struct surface_param_s)); if ((obj_buffer->num_elements != 1) || ((obj_buffer->size != sizeof(struct surface_param_s)) && (obj_buffer->size != sizeof(VAProcPipelineParameterBuffer)))) { return VA_STATUS_ERROR_UNKNOWN; } /* yuv rotation issued from dec driver, TODO removed later */ if (obj_buffer->type == YUVProcessorSurfaceType) { surface_param_p surface_params = (surface_param_p) obj_buffer->buffer_data; ctx->display_width = surface_params->display_width; ctx->display_height = surface_params->display_height; ctx->coded_width = surface_params->coded_width; ctx->coded_height = surface_params->coded_height; ctx->src_surface = dec_ctx->obj_context->current_render_target->psb_surface; ctx->proc_param = NULL; } else if (obj_buffer->type == VAProcPipelineParameterBufferType) { VAProcPipelineParameterBuffer *vpp_params = (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data; object_surface_p obj_surface = SURFACE(vpp_params->surface); psb_surface_p rotate_surface = dec_ctx->obj_context->current_render_target->psb_surface; if (obj_surface == NULL){ vaStatus = VA_STATUS_ERROR_UNKNOWN; return vaStatus; } //ctx->display_width = ((vpp_params->surface_region->width + 0xf) & ~0xf); //ctx->display_height = ((vpp_params->surface_region->height + 0x1f) & ~0x1f); ctx->display_width = ((obj_surface->width + 0xf) & ~0xf); ctx->display_height = ((obj_surface->height + 0xf) & ~0xf); ctx->coded_width = ctx->display_width; ctx->coded_height = ctx->display_height; ctx->src_surface = obj_surface->psb_surface; #ifndef BAYTRAIL dec_ctx->obj_context->msvdx_rotate = vpp_params->rotation_state; #endif SET_SURFACE_INFO_rotate(rotate_surface, dec_ctx->obj_context->msvdx_rotate); ctx->proc_param = vpp_params; obj_buffer->buffer_data = NULL; obj_buffer->size = 0; #ifdef PSBVIDEO_MSVDX_DEC_TILING object_context_p obj_context = dec_ctx->obj_context; psb_driver_data_p driver_data = obj_context->driver_data; drv_debug_msg(VIDEO_DEBUG_GENERAL, "attempt to update tile context\n"); if (GET_SURFACE_INFO_tiling(ctx->src_surface)) { drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context\n"); unsigned long msvdx_tile = psb__tile_stride_log2_256(rotate_surface->stride); 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); LOGE("update tile context, msvdx_tiled is 0x%08x", obj_context->msvdx_tile); } #endif } #ifdef ADNROID LOGV("%s, %d %d %d %d***************************************************\n", __func__, ctx->display_width, ctx->display_height, ctx->coded_width, ctx->coded_height); #endif vaStatus = VA_STATUS_SUCCESS; if (psb_context_get_next_cmdbuf(dec_ctx->obj_context)) { vaStatus = VA_STATUS_ERROR_UNKNOWN; DEBUG_FAILURE; return vaStatus; } /* ctx->begin_slice(ctx, slice_param); */ vld_dec_FE_state(dec_ctx->obj_context, NULL); tng__yuv_processor_process(dec_ctx); /* ctx->process_slice(ctx, slice_param); */ vld_dec_write_kick(dec_ctx->obj_context); dec_ctx->obj_context->video_op = psb_video_vld; dec_ctx->obj_context->flags = 0; /* ctx->end_slice(ctx); */ dec_ctx->obj_context->flags = FW_VA_RENDER_IS_FIRST_SLICE | FW_VA_RENDER_IS_LAST_SLICE | FW_INTERNAL_CONTEXT_SWITCH; if (psb_context_submit_cmdbuf(dec_ctx->obj_context)) { vaStatus = VA_STATUS_ERROR_UNKNOWN; } return vaStatus; }