Пример #1
0
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;
    }

}
Пример #2
0
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
}