Exemplo n.º 1
0
static VAStatus
intel_encoder_check_yuv_surface(VADriverContextP ctx,
                                VAProfile profile,
                                struct encode_state *encode_state,
                                struct intel_encoder_context *encoder_context)
{
    struct i965_driver_data *i965 = i965_driver_data(ctx);
    struct i965_surface src_surface, dst_surface;
    struct object_surface *obj_surface;
    VAStatus status;
    VARectangle rect;

    /* releae the temporary surface */
    if (encoder_context->is_tmp_id) {
        i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
        encode_state->input_yuv_object = NULL;
    }

    encoder_context->is_tmp_id = 0;
    obj_surface = SURFACE(encode_state->current_render_target);
    assert(obj_surface && obj_surface->bo);

    if (!obj_surface || !obj_surface->bo)
        return VA_STATUS_ERROR_INVALID_PARAMETER;

    if (obj_surface->fourcc == VA_FOURCC_NV12) {
        unsigned int tiling = 0, swizzle = 0;

        dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);

        if (tiling == I915_TILING_Y) {
            encoder_context->input_yuv_surface = encode_state->current_render_target;
            encode_state->input_yuv_object = obj_surface;
            return VA_STATUS_SUCCESS;
        }
    }

    rect.x = 0;
    rect.y = 0;
    rect.width = obj_surface->orig_width;
    rect.height = obj_surface->orig_height;
    
    src_surface.base = (struct object_base *)obj_surface;
    src_surface.type = I965_SURFACE_TYPE_SURFACE;
    src_surface.flags = I965_SURFACE_FLAG_FRAME;
    
    status = i965_CreateSurfaces(ctx,
                                 obj_surface->orig_width,
                                 obj_surface->orig_height,
                                 VA_RT_FORMAT_YUV420,
                                 1,
                                 &encoder_context->input_yuv_surface);
    assert(status == VA_STATUS_SUCCESS);

    if (status != VA_STATUS_SUCCESS)
        return status;

    obj_surface = SURFACE(encoder_context->input_yuv_surface);
    encode_state->input_yuv_object = obj_surface;
    assert(obj_surface);
    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
    
    dst_surface.base = (struct object_base *)obj_surface;
    dst_surface.type = I965_SURFACE_TYPE_SURFACE;
    dst_surface.flags = I965_SURFACE_FLAG_FRAME;

    status = i965_image_processing(ctx,
                                   &src_surface,
                                   &rect,
                                   &dst_surface,
                                   &rect);
    assert(status == VA_STATUS_SUCCESS);

    encoder_context->is_tmp_id = 1;

    return VA_STATUS_SUCCESS;
}
Exemplo n.º 2
0
/* Ensure the supplied VA surface has valid storage for decoding the
   current picture */
VAStatus
avc_ensure_surface_bo(
    VADriverContextP                    ctx,
    struct decode_state                *decode_state,
    struct object_surface              *obj_surface,
    const VAPictureParameterBufferH264 *pic_param
)
{
    VAStatus va_status;
    uint32_t hw_fourcc, fourcc, subsample, chroma_format;

    /* Validate chroma format */
    switch (pic_param->seq_fields.bits.chroma_format_idc) {
    case 0: // Grayscale
        fourcc = VA_FOURCC_Y800;
        subsample = SUBSAMPLE_YUV400;
        chroma_format = VA_RT_FORMAT_YUV400;
        break;
    case 1: // YUV 4:2:0
        fourcc = VA_FOURCC_NV12;
        subsample = SUBSAMPLE_YUV420;
        chroma_format = VA_RT_FORMAT_YUV420;
        break;
    default:
        return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
    }

    /* Determine the HW surface format, bound to VA config needs */
    if ((decode_state->base.chroma_formats & chroma_format) == chroma_format)
        hw_fourcc = fourcc;
    else {
        hw_fourcc = 0;
        switch (fourcc) {
        case VA_FOURCC_Y800: // Implement with an NV12 surface
            if (decode_state->base.chroma_formats & VA_RT_FORMAT_YUV420) {
                hw_fourcc = VA_FOURCC_NV12;
                subsample = SUBSAMPLE_YUV420;
            }
            break;
        }
    }
    if (!hw_fourcc)
        return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;

    /* (Re-)allocate the underlying surface buffer store, if necessary */
    if (!obj_surface->bo || obj_surface->fourcc != hw_fourcc) {
        struct i965_driver_data * const i965 = i965_driver_data(ctx);

        i965_destroy_surface_storage(obj_surface);
        va_status = i965_check_alloc_surface_bo(ctx, obj_surface,
            i965->codec_info->has_tiled_surface, hw_fourcc, subsample);
        if (va_status != VA_STATUS_SUCCESS)
            return va_status;
    }

    /* Fake chroma components if grayscale is implemented on top of NV12 */
    if (fourcc == VA_FOURCC_Y800 && hw_fourcc == VA_FOURCC_NV12) {
        const uint32_t uv_offset = obj_surface->width * obj_surface->height;
        const uint32_t uv_size   = obj_surface->width * obj_surface->height / 2;

        drm_intel_gem_bo_map_gtt(obj_surface->bo);
        memset(obj_surface->bo->virtual + uv_offset, 0x80, uv_size);
        drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
    }
    return VA_STATUS_SUCCESS;
}