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;
}
Example #4
0
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;
}