예제 #1
0
// Create VA buffer object
object_buffer_p
create_va_buffer(
    vdpau_driver_data_t *driver_data,
    VAContextID         context,
    VABufferType        buffer_type,
    unsigned int        num_elements,
    unsigned int        size
)
{
    VABufferID buffer_id;
    object_buffer_p obj_buffer;

    buffer_id = object_heap_allocate(&driver_data->buffer_heap);
    if (buffer_id == VA_INVALID_BUFFER)
        return NULL;

    obj_buffer = VDPAU_BUFFER(buffer_id);
    if (!obj_buffer)
        return NULL;

    obj_buffer->va_context       = context;
    obj_buffer->type             = buffer_type;
    obj_buffer->max_num_elements = num_elements;
    obj_buffer->num_elements     = num_elements;
    obj_buffer->buffer_size      = size * num_elements;
    obj_buffer->buffer_data      = malloc(obj_buffer->buffer_size);
    obj_buffer->mtime            = 0;
    obj_buffer->delayed_destroy  = 0;

    if (!obj_buffer->buffer_data) {
        destroy_va_buffer(driver_data, obj_buffer);
        return NULL;
    }
    return obj_buffer;
}
VAStatus rockchip_CreateImage(
    VADriverContextP ctx,
    VAImageFormat *format,
    int width,
    int height,
    VAImage *out_image
)
{
    INIT_DRIVER_DATA
    VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;

    if (!format || !out_image)
        return VA_STATUS_ERROR_INVALID_PARAMETER;

    out_image->image_id = VA_INVALID_ID;
    out_image->buf = VA_INVALID_ID;

    VAImageID image_id = object_heap_allocate(&driver_data->image_heap);
    if (image_id == VA_INVALID_ID) {
        va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
        goto error;
    }

    object_image_p obj_image = IMAGE(image_id);
    if (!obj_image) {
        va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
        goto error;
    }

    obj_image->ref_cnt = 1;

    VAImage * const image = &obj_image->image;
    image->image_id = image_id;
    image->buf = VA_INVALID_ID;

    switch (format->fourcc) {
    case VA_FOURCC_NV12:
        image->num_planes = 2;
        image->pitches[0] = width;
        image->offsets[0] = 0;
        image->pitches[1] = width;
        image->offsets[1] = width * height;
        image->data_size = width * height * 3 / 2;
        image->num_palette_entries = 0;
        image->entry_bytes = 0;
        image->component_order[0] = 'Y';
        image->component_order[1] = 'U';
        image->component_order[2] = 'V';
        image->component_order[3] = '\0';
        break;
    case VA_FOURCC_YV12:
    case VA_FOURCC_IYUV:
        image->num_planes = 3;
        image->pitches[0] = width;
        image->offsets[0] = 0;
        image->pitches[1] = width / 2;
        image->offsets[1] = width * height;
        image->pitches[2] = width / 2;
        image->offsets[2] = width * height * 5 / 4;
        image->data_size = width * height * 3 / 2;
        image->num_palette_entries = 0;
        image->entry_bytes = 0;
        image->component_order[0] = 'Y';
        image->component_order[1] = 'U';
        image->component_order[2] = 'V';
        image->component_order[3] = '\0';
        break;
    default:
        goto error;
    }

    va_status = rockchip_CreateBuffer(ctx, 0, VAImageBufferType,
                                      image->data_size, 1, NULL,
                                      &image->buf);
    if (va_status != VA_STATUS_SUCCESS)
        goto error;

    object_buffer_p obj_buffer = BUFFER(image->buf);
    if (!obj_buffer)
        goto error;

    image->image_id = image_id;
    image->format = *format;
    image->width = width;
    image->height = height;

    *out_image = *image;

    return VA_STATUS_SUCCESS;

error:
    rockchip_DestroyImage(ctx, image_id);
    return va_status;
}