static void compile_huffman_tables(context_JPEG_p ctx) { VAStatus vaStatus = VA_STATUS_SUCCESS; ctx->huffman_table_space = 1984; if (0 == psb_buffer_map(&ctx->vlc_packed_table, &ctx->huffman_table_RAM)) { // Compile Tables uint32_t table_class; uint32_t table_id; for (table_class = 0; table_class < TABLE_CLASS_NUM; table_class++) { for (table_id = 0; table_id < JPEG_MAX_SETS_HUFFMAN_TABLES; table_id++) { if (ctx->symbol_stats[table_class][table_id].num_codes) { JPG_VLC_CompileTable(ctx->symbol_codes[table_class][table_id], &ctx->symbol_stats[table_class][table_id], ctx->huffman_table_space, ctx->huffman_table_RAM, &ctx->table_stats[table_class][table_id]); ctx->huffman_table_space -= ctx->table_stats[table_class][table_id].size; ctx->huffman_table_RAM += ctx->table_stats[table_class][table_id].size; } } } psb_buffer_unmap(&ctx->vlc_packed_table); } else { vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; DEBUG_FAILURE; } }
static VAStatus vsp_VP8_BeginPicture( object_context_p obj_context) { int ret; VAStatus vaStatus = VA_STATUS_SUCCESS; INIT_CONTEXT_VPP; vsp_cmdbuf_p cmdbuf; /* Initialise the command buffer */ ret = vsp_context_get_next_cmdbuf(ctx->obj_context); if (ret) { drv_debug_msg(VIDEO_DEBUG_GENERAL, "get next cmdbuf fail\n"); vaStatus = VA_STATUS_ERROR_UNKNOWN; return vaStatus; } cmdbuf = obj_context->vsp_cmdbuf; if (ctx->obj_context->frame_count == 0) { /* first picture */ vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VP8_ID, ctx->context_buf, Vss_Sys_STATE_BUF_COMMAND, 0, VSP_VP8ENC_STATE_SIZE); } /* map param mem */ vaStatus = psb_buffer_map(&cmdbuf->param_mem, &cmdbuf->param_mem_p); if (vaStatus) { return vaStatus; } cmdbuf->pic_param_p = cmdbuf->param_mem_p; cmdbuf->seq_param_p = cmdbuf->param_mem_p + ctx->seq_param_offset; cmdbuf->ref_param_p = cmdbuf->param_mem_p + ctx->ref_param_offset; ctx->vp8_seq_cmd_send = 0; ctx->re_send_seq_params = 0; return VA_STATUS_SUCCESS; }
/* * 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; }
void psb_RecalcAlternativeOutput(object_context_p obj_context) { psb_driver_data_p driver_data = obj_context->driver_data; object_surface_p obj_surface = obj_context->current_render_target; int angle, new_rotate, i; int old_rotate = driver_data->msvdx_rotate_want; int mode = INIT_VALUE; #ifdef TARGET_HAS_MULTIPLE_DISPLAY mode = psb_android_get_mds_mode((void*)driver_data->ws_priv); #endif if (mode != INIT_VALUE) { // clear device rotation info if (driver_data->mipi0_rotation != VA_ROTATION_NONE) { driver_data->mipi0_rotation = VA_ROTATION_NONE; driver_data->hdmi_rotation = VA_ROTATION_NONE; } // Disable msvdx rotation if // WIDI video is play and meta data rotation angle is 0 if (mode == WIDI_VIDEO_ISPLAYING) { if (driver_data->va_rotate == VA_ROTATION_NONE) driver_data->disable_msvdx_rotate = 1; else { driver_data->mipi0_rotation = 0; driver_data->hdmi_rotation = 0; driver_data->disable_msvdx_rotate = 0; } } else { if (IS_MOFD(driver_data)) driver_data->disable_msvdx_rotate = 1; else driver_data->disable_msvdx_rotate = driver_data->disable_msvdx_rotate_backup; } } else if (IS_MOFD(driver_data)) { /* Moorefield has overlay rotaion, so decoder doesn't generate rotation * output according to windows manager. It is controlled by payload info * in which HWC signal decoder to generate rotation output */ long long hwc_timestamp = 0; int index = -1; for (i = 0; i < obj_context->num_render_targets; i++) { object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]); /* traverse all surfaces' share info to find out the latest transform info */ if (obj_surface && obj_surface->share_info) { if (obj_surface->share_info->hwc_timestamp > hwc_timestamp) { hwc_timestamp = obj_surface->share_info->hwc_timestamp; index = i; } } } if (index >= 0) { object_surface_p obj_surface = SURFACE(obj_context->render_targets[index]); if (obj_surface && obj_surface->share_info) { int transform = obj_surface->share_info->layer_transform; driver_data->mipi0_rotation = HAL2VAROTATION(transform); drv_debug_msg(VIDEO_DEBUG_GENERAL, "Signal from HWC to rotate %d\n", driver_data->mipi0_rotation); } } } else if (driver_data->native_window) { int display_rotate = 0; psb_android_surfaceflinger_rotate(driver_data->native_window, &display_rotate); drv_debug_msg(VIDEO_DEBUG_GENERAL, "NativeWindow(0x%x), get surface flinger rotate %d\n", driver_data->native_window, display_rotate); if (driver_data->mipi0_rotation != display_rotate) { driver_data->mipi0_rotation = display_rotate; } } else { long long hwc_timestamp = 0; int index = -1; for (i = 0; i < obj_context->num_render_targets; i++) { object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]); /* traverse all surfaces' share info to find out the latest transform info */ if (obj_surface && obj_surface->share_info) { if (obj_surface->share_info->hwc_timestamp > hwc_timestamp) { hwc_timestamp = obj_surface->share_info->hwc_timestamp; index = i; } } } if (index >= 0) { object_surface_p obj_surface = SURFACE(obj_context->render_targets[index]); if (obj_surface && obj_surface->share_info) { int transform = obj_surface->share_info->layer_transform; driver_data->mipi0_rotation = HAL2VAROTATION(transform); } } } #ifdef PSBVIDEO_MRFL if ((mode == HDMI_VIDEO_ISPLAYING) && driver_data->native_window) { int display_rotate = 0; psb_android_surfaceflinger_rotate(driver_data->native_window, &display_rotate); drv_debug_msg(VIDEO_DEBUG_GENERAL, "NativeWindow(0x%x), get surface flinger rotate %d\n", driver_data->native_window, display_rotate); if (driver_data->mipi0_rotation != display_rotate && !IS_MOFD(driver_data)) { driver_data->mipi0_rotation = display_rotate; } } #endif /* calc VA rotation and WM rotation, and assign to the final rotation degree */ angle = Rotation2Angle(driver_data->va_rotate) + Rotation2Angle(driver_data->mipi0_rotation); driver_data->local_rotation = Angle2Rotation(angle); angle = Rotation2Angle(driver_data->va_rotate) + Rotation2Angle(driver_data->hdmi_rotation); driver_data->extend_rotation = Angle2Rotation(angle); /* On MOFD, no need to use meta rotation, just use rotation angle signal from HWC */ if (IS_MOFD(driver_data)) { driver_data->local_rotation = driver_data->mipi0_rotation; driver_data->extend_rotation = Rotation2Angle(driver_data->hdmi_rotation); } /* for any case that local and extened rotation are not same, fallback to GPU */ if ((driver_data->mipi1_rotation != VA_ROTATION_NONE) || ((driver_data->local_rotation != VA_ROTATION_NONE) && (driver_data->extend_rotation != VA_ROTATION_NONE) && (driver_data->local_rotation != driver_data->extend_rotation))) { new_rotate = ROTATE_VA2MSVDX(driver_data->local_rotation); if (driver_data->is_android == 0) /*fallback to texblit path*/ driver_data->output_method = PSB_PUTSURFACE_CTEXTURE; } else { if (driver_data->local_rotation == VA_ROTATION_NONE) new_rotate = driver_data->extend_rotation; else new_rotate = driver_data->local_rotation; if (driver_data->is_android == 0) { if (driver_data->output_method != PSB_PUTSURFACE_FORCE_CTEXTURE) driver_data->output_method = PSB_PUTSURFACE_COVERLAY; } } if (old_rotate != new_rotate) { drv_debug_msg(VIDEO_DEBUG_GENERAL, "MSVDX: new rotation %d desired\n", new_rotate); driver_data->msvdx_rotate_want = new_rotate; } #ifdef TARGET_HAS_MULTIPLE_DISPLAY int scaling_buffer_width = 1920, scaling_buffer_height = 1080 ; int scaling_width = 0, scaling_height = 0; int scaling_offset_x = 0, scaling_offset_y = 0; int old_bufw = 0, old_bufh = 0, old_x = 0, old_y = 0, old_w = 0, old_h = 0; int bScaleChanged = 0, size = 0; unsigned char * surface_data; int ret = psb_android_get_mds_decoder_output_resolution( (void*)driver_data->ws_priv, &scaling_width, &scaling_height, &scaling_offset_x, &scaling_offset_y, &scaling_buffer_width, &scaling_buffer_height); if ((old_bufw != scaling_buffer_width) || (old_bufh != scaling_buffer_height) || (old_x != scaling_offset_x) || (old_y != scaling_offset_y) || (old_w != scaling_width) || (old_h != scaling_height)) { bScaleChanged = 1; } old_x = scaling_offset_x; old_y = scaling_offset_y; old_w = scaling_width; old_h = scaling_height; old_bufw = scaling_buffer_width; old_bufh = scaling_buffer_height; /* turn off ved downscaling if width and height are 0. * Besides, scaling_width and scaling_height must be a multiple of 2. */ if (!ret || (!scaling_width || !scaling_height) || (scaling_width & 1) || (scaling_height & 1)) { obj_context->msvdx_scaling = 0; obj_context->scaling_width = 0; obj_context->scaling_height = 0; obj_context->scaling_offset_x= 0; obj_context->scaling_offset_y = 0; obj_context->scaling_buffer_width = 0; obj_context->scaling_buffer_height = 0; } else { obj_context->msvdx_scaling = 1; obj_context->scaling_width = scaling_width; obj_context->scaling_height = scaling_height; obj_context->scaling_offset_x= scaling_offset_x; obj_context->scaling_offset_y = scaling_offset_y; obj_context->scaling_buffer_width = scaling_buffer_width; obj_context->scaling_buffer_height = scaling_buffer_height; } if (bScaleChanged) { if ((obj_surface != NULL) && (obj_surface->out_loop_surface != NULL)) { if (psb_buffer_map(&obj_surface->out_loop_surface->buf, &surface_data)) { drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to map rotation buffer before clear it"); } else { size = obj_surface->out_loop_surface->chroma_offset; memset(surface_data, 0, size); memset(surface_data + size, 0x80, obj_surface->out_loop_surface->size - size); psb_buffer_unmap(&obj_context->current_render_target->out_loop_surface->buf); } } } #endif }