From 5c73d6a5f1e4fd58eef2135e7d928be1155a625c Mon Sep 17 00:00:00 2001 From: Devarsh Thakkar Date: Thu, 5 Jan 2017 01:42:32 -0800 Subject: [PATCH 8/9] kmssink : Allocate dumb buffers with bpp as per video format - The kmssink uses libkms API kms_bo_create to create buffer object. Now since kms_bo_create uses hardcoded bits-per-pixel value set to 32, overallocation is happening and wrong bpp are getting passed to xilinx dpdma driver, due to which xilinx dpdma driver is returning incorrect pitch value. - Fix this by calculating bpp as per the video format and use drm IOCTL directly instead of using libkms API. Reference : https://lists.freedesktop.org/archives/dri-devel/2014-December/073686.html Signed-off-by: Devarsh Thakkar Upstream Status: Backport --- sys/kms/gstkmsallocator.c | 109 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 15 deletions(-) diff --git a/sys/kms/gstkmsallocator.c b/sys/kms/gstkmsallocator.c index d368397..6ddf357 100644 --- a/sys/kms/gstkmsallocator.c +++ b/sys/kms/gstkmsallocator.c @@ -46,6 +46,23 @@ struct _GstKMSAllocatorPrivate struct kms_driver *driver; }; +struct kms_bo +{ + struct kms_driver *kms; + void *ptr; + size_t size; + size_t offset; + size_t pitch; + unsigned handle; +}; + + +struct dumb_bo +{ + struct kms_bo base; + unsigned map_count; +}; + #define parent_class gst_kms_allocator_parent_class G_DEFINE_TYPE_WITH_CODE (GstKMSAllocator, gst_kms_allocator, GST_TYPE_ALLOCATOR, G_ADD_PRIVATE (GstKMSAllocator); @@ -120,17 +137,9 @@ static gboolean gst_kms_allocator_memory_create (GstKMSAllocator * allocator, GstKMSMemory * kmsmem, GstVideoInfo * vinfo) { - gint ret; - guint attrs[] = { - KMS_WIDTH, GST_VIDEO_INFO_WIDTH (vinfo), - KMS_HEIGHT, GST_VIDEO_INFO_HEIGHT (vinfo), - KMS_TERMINATE_PROP_LIST, - }; - guint i, virt_height = 0; - - for (i = 0; i < vinfo->finfo->n_planes; i++) - virt_height += GST_VIDEO_INFO_HEIGHT (vinfo) >> vinfo->finfo->h_sub[i]; - attrs[3] = virt_height; + gint ret, bpp, virtual_height; + struct drm_mode_create_dumb arg; + struct dumb_bo *bo; if (kmsmem->bo) return TRUE; @@ -138,13 +147,83 @@ gst_kms_allocator_memory_create (GstKMSAllocator * allocator, if (!ensure_kms_driver (allocator)) return FALSE; - ret = kms_bo_create (allocator->priv->driver, attrs, &kmsmem->bo); + switch (GST_VIDEO_INFO_FORMAT (vinfo)) { + case GST_VIDEO_FORMAT_NV12: + case GST_VIDEO_FORMAT_NV21: + case GST_VIDEO_FORMAT_NV16: + case GST_VIDEO_FORMAT_NV61: + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + bpp = 8; + break; + + case GST_VIDEO_FORMAT_UYVY: + case GST_VIDEO_FORMAT_YVYU: + case GST_VIDEO_FORMAT_YUY2: + bpp = 16; + break; + + case GST_VIDEO_FORMAT_BGR: + case GST_VIDEO_FORMAT_RGB: + bpp = 24; + break; + + case GST_VIDEO_FORMAT_ARGB: + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_xBGR: + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_BGRA: + case GST_VIDEO_FORMAT_BGRx: + bpp = 32; + break; + + default: + GST_ERROR_OBJECT (allocator, "Unsupported format 0x%08x\n", GST_VIDEO_INFO_FORMAT (vinfo)); + + return NULL; + } + + switch (GST_VIDEO_INFO_FORMAT (vinfo)) { + case GST_VIDEO_FORMAT_NV12: + case GST_VIDEO_FORMAT_NV21: + virtual_height = GST_VIDEO_INFO_HEIGHT (vinfo) * 3 / 2; + break; + + case GST_VIDEO_FORMAT_NV16: + case GST_VIDEO_FORMAT_NV61: + virtual_height = GST_VIDEO_INFO_HEIGHT (vinfo) * 2; + break; + + default: + virtual_height = GST_VIDEO_INFO_HEIGHT (vinfo); + break; + } + + bo = calloc(1, sizeof(*bo)); + if (!bo) + return -ENOMEM; + + memset(&arg, 0, sizeof(arg)); + arg.bpp = bpp; + arg.width = GST_VIDEO_INFO_WIDTH (vinfo); + arg.height = virtual_height; + + ret = drmIoctl(allocator->priv->fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg); if (ret) { - GST_ERROR_OBJECT (allocator, "Failed to create buffer object: %s (%d)", - strerror (-ret), ret); - return FALSE; + GST_ERROR_OBJECT (allocator, "Failed to create buffer object: %s (%d)", + strerror (-ret), ret); + return FALSE; } + bo->base.kms = allocator->priv->driver; + bo->base.handle = arg.handle; + bo->base.size = arg.size; + bo->base.pitch = arg.pitch; + + kmsmem->bo = &bo->base; + return TRUE; } -- 2.7.4