fix: not displaying non-4 aligned video 26/9126/1
authorBoram Park <boram1288.park@samsung.com>
Tue, 7 May 2013 12:11:35 +0000 (21:11 +0900)
committerBoram Park <boram1288.park@samsung.com>
Mon, 2 Sep 2013 08:04:49 +0000 (17:04 +0900)
Change-Id: I3cc3795533f908d59a1056b2f9507c8c7a4f4a71

packaging/xorg-x11-drv-emulfb.spec
src/util/fbdev_util.c
src/util/fbdev_util.h
src/xv/arm/fbdev_video_v4l2.c
src/xv/fbdev_video.c
src/xv/fbdev_video.h
src/xv/i386/fbdev_video_v4l2.c

index 15cf4a5..961c1ee 100644 (file)
@@ -3,7 +3,7 @@
 
 Name:       xorg-x11-drv-emulfb
 Summary:    X.Org X server driver for sdk emulation
-Version:    0.5.7
+Version:    0.5.8
 Release:    1
 #ExclusiveArch:  %arm
 Group:      System/X Hardware Support
index 92136df..cb1e219 100644 (file)
@@ -240,6 +240,62 @@ fbdev_util_align_rect (int src_w, int src_h, int dst_w, int dst_h, xRectangle *f
        fit->height = fit_height;
 }
 
+static void *
+_copy_one_channel (int width, int height,
+                   char *s, int s_size_w, int s_pitches,
+                   char *d, int d_size_w, int d_pitches)
+{
+    unsigned char *src = (unsigned char*)s;
+    unsigned char *dst = (unsigned char*)d;
+
+    if (d_size_w == width && s_size_w == width)
+        memcpy (dst, src, width * height);
+    else
+    {
+        int i;
+
+        for (i = 0; i < height; i++)
+        {
+            memcpy (dst, src, width);
+            src += s_pitches;
+            dst += d_pitches;
+        }
+    }
+
+    return dst;
+}
+
+void*
+fbdev_util_copy_image (int width, int height,
+                       char *s, int s_size_w, int s_size_h,
+                       int *s_pitches, int *s_offsets, int *s_lengths,
+                       char *d, int d_size_w, int d_size_h,
+                       int *d_pitches, int *d_offsets, int *d_lengths,
+                       int channel, int h_sampling, int v_sampling)
+{
+    int i;
+
+    for (i = 0; i < channel; i++)
+    {
+        int c_width = width;
+        int c_height = height;
+
+        if (i > 0)
+        {
+            c_width = c_width / h_sampling;
+            c_height = c_height / v_sampling;
+        }
+
+        _copy_one_channel (c_width, c_height,
+                           s, s_size_w, s_pitches[i],
+                           d, d_size_w, d_pitches[i]);
+
+        s = s + s_lengths[i];
+        d = d + d_lengths[i];
+    }
+
+    return d;
+}
 
 void
 drvlog (const char * f, ...)
index 206daeb..27f4b21 100644 (file)
@@ -79,4 +79,11 @@ void fbdev_util_rotate_rect (int xres, int yres, int src_rot, int dst_rot, xRect
 const PropertyPtr fbdev_util_get_window_property(WindowPtr pWin, const char* prop_name);
 void fbdev_util_align_rect (int src_w, int src_h, int dst_w, int dst_h, xRectangle *fit, Bool hw);
 
+void* fbdev_util_copy_image (int width, int height,
+                             char *s, int s_size_w, int s_size_h,
+                             int *s_pitches, int *s_offsets, int *s_lengths,
+                             char *d, int d_size_w, int d_size_h,
+                             int *d_pitches, int *d_offsets, int *d_lengths,
+                             int channel, int h_sampling, int v_sampling);
+
 #endif  /* __FBDEV_UTIL_H__ */
\ No newline at end of file
index 69ea300..49b8df5 100644 (file)
@@ -756,7 +756,7 @@ fbdevVideoV4l2StreamOff (void *handle)
                size = fbdevVideoQueryImageAttributes (NULL, hdisp->status.id,
                                                       (unsigned short*)&hdisp->status.img.width,
                                                       (unsigned short*)&hdisp->status.img.height,
-                                                      NULL, NULL);
+                                                      NULL, NULL, NULL);
 
                if (size > 0)
                        hdisp->status.backup = malloc (size);
@@ -979,7 +979,7 @@ fbdevVideoV4l2Draw (void *handle, uchar *buf, uint *phy_addrs)
                size = fbdevVideoQueryImageAttributes (NULL, hdisp->status.id,
                                                       (unsigned short*)&hdisp->status.img.width,
                                                       (unsigned short*)&hdisp->status.img.height,
-                                                      NULL, NULL);
+                                                      NULL, NULL, NULL);
                memcpy (destbuf, buf, size);
        }
 
index 1864e08..444277a 100644 (file)
@@ -196,6 +196,13 @@ _fbdevVideoCloseV4l2Handle (ScrnInfoPtr pScrnInfo, FBDevPortPrivPtr pPortPriv)
 
        pPortPriv->v4l2_handle = NULL;
        pPortPriv->v4l2_index = -1;
+
+    if (pPortPriv->aligned_buffer)
+    {
+        free (pPortPriv->aligned_buffer);
+        pPortPriv->aligned_buffer = NULL;
+        pPortPriv->aligned_width = 0;
+    }
 }
 
 static Atom
@@ -526,6 +533,42 @@ _fbdevVideoPutImageOnDrawable (ScrnInfoPtr pScrnInfo,
                break;
        }
 
+    if (image_info->id == FOURCC_I420 && img->width % 16)
+    {
+        int src_p[3] = {0,}, src_o[3] = {0,}, src_l[3] = {0,};
+        int dst_p[3] = {0,}, dst_o[3] = {0,}, dst_l[3] = {0,};
+        unsigned short src_w, src_h, dst_w, dst_h;
+        int size;
+
+        src_w = img->width;
+        src_h = img->height;
+        fbdevVideoQueryImageAttributes (NULL, image_info->id, &src_w, &src_h,
+                                        src_p, src_o, src_l);
+
+        dst_w = (img->width + 15) & ~15;
+        dst_h = img->height;
+        size = fbdevVideoQueryImageAttributes (NULL, image_info->id, &dst_w, &dst_h,
+                                               dst_p, dst_o, dst_l);
+
+        if (!pPortPriv->aligned_buffer)
+        {
+            pPortPriv->aligned_buffer = malloc (size);
+            if (!pPortPriv->aligned_buffer)
+                return FALSE;
+        }
+
+        fbdev_util_copy_image (src_w, src_h,
+                               (char*)buf, src_w, src_h,
+                               src_p, src_o, src_l,
+                               (char*)pPortPriv->aligned_buffer, dst_w, dst_h,
+                               dst_p, dst_o, dst_l,
+                               3, 2, 2);
+
+        pPortPriv->aligned_width = dst_w;
+        img->width = dst_w;
+        buf = pPortPriv->aligned_buffer;
+    }
+
        /* support only RGB  */
        fbdev_pixman_convert_image (PIXMAN_OP_SRC,
                                    buf, pPixmap->devPrivate.ptr,
@@ -756,6 +799,13 @@ FBDevVideoStop (ScrnInfoPtr pScrnInfo, pointer data, Bool exit)
 #endif
        }
 
+    if (pPortPriv->aligned_buffer)
+    {
+        free (pPortPriv->aligned_buffer);
+        pPortPriv->aligned_buffer = NULL;
+        pPortPriv->aligned_width = 0;
+    }
+
        pPortPriv->mode = PORT_MODE_INIT;
        pPortPriv->preemption = 0;
        pPortPriv->rotate = -1;
@@ -782,7 +832,8 @@ fbdevVideoQueryImageAttributes (ScrnInfoPtr    pScrnInfo,
                                 unsigned short *w,
                                 unsigned short *h,
                                 int            *pitches,
-                                int            *offsets)
+                                int            *offsets,
+                                int            *lengths)
 {
        int size = 0, tmp = 0;
 
@@ -797,18 +848,24 @@ fbdevVideoQueryImageAttributes (ScrnInfoPtr    pScrnInfo,
                if (pitches)
                        pitches[0] = size;
                size *= *h;
+        if (lengths)
+            lengths[0] = size;
                break;
        case FOURCC_RGB24:
                size += (*w << 1) + *w;
                if (pitches)
                        pitches[0] = size;
                size *= *h;
+        if (lengths)
+            lengths[0] = size;
                break;
        case FOURCC_RGB32:
                size += (*w << 2);
                if (pitches)
                        pitches[0] = size;
                size *= *h;
+        if (lengths)
+            lengths[0] = size;
                break;
        case FOURCC_I420:
        case FOURCC_S420:
@@ -821,6 +878,8 @@ fbdevVideoQueryImageAttributes (ScrnInfoPtr    pScrnInfo,
                size *= *h;
                if (offsets)
                        offsets[1] = size;
+        if (lengths)
+            lengths[0] = size;
 
                tmp = ((*w >> 1) + 3) & ~3;
                if (pitches)
@@ -830,8 +889,13 @@ fbdevVideoQueryImageAttributes (ScrnInfoPtr    pScrnInfo,
                size += tmp;
                if (offsets)
                        offsets[2] = size;
+        if (lengths)
+            lengths[1] = tmp;
 
                size += tmp;
+        if (lengths)
+            lengths[2] = tmp;
+
                break;
        case FOURCC_UYVY:
        case FOURCC_SUYV:
@@ -868,6 +932,38 @@ fbdevVideoQueryImageAttributes (ScrnInfoPtr    pScrnInfo,
 }
 
 static int
+FBDEVVideoQueryImageAttributes (ScrnInfoPtr    pScrnInfo,
+                                int            id,
+                                unsigned short *w,
+                                unsigned short *h,
+                                int            *pitches,
+                                int            *offsets)
+{
+    return fbdevVideoQueryImageAttributes (pScrnInfo, id, w, h, pitches, offsets, NULL);
+}
+
+int secUtilDumpRaw (const char * file, const void * data, int size)
+{
+//     int i;
+    unsigned int * blocks;
+
+    FILE * fp = fopen (file, "w+");
+    if (fp == NULL)
+    {
+        return 0;
+    }
+    else
+    {
+        blocks = (unsigned int*)data;
+        fwrite (blocks, 1, size, fp);
+
+        fclose (fp);
+    }
+
+    return 0;
+}
+
+static int
 FBDevVideoPutImage (ScrnInfoPtr pScrnInfo,
                     short src_x, short src_y, short dst_x, short dst_y,
                     short src_w, short src_h, short dst_w, short dst_h,
@@ -906,6 +1002,11 @@ FBDevVideoPutImage (ScrnInfoPtr pScrnInfo,
                return BadRequest;
        }
 
+  static int i;
+  char name[128];
+  sprintf (name, "/mnt/host/temp/xv_%d_%d_%d.yuv", width, height, i++);
+  secUtilDumpRaw (name, buf, ((width+3)&~3)*height*1.5);
+
        _fbdevVideoGetRotation (pScreen, pPortPriv, pDraw, &scn_rotate, &rotate, &hw_rotate);
 
        DRVLOG ("[PutImage] buf(%p) ID(%c%c%c%c) mode(%s) preem(%d) handle(%p) rot(%d+%d=%d) res(%dx%d) drawing(%d)\n",
@@ -1009,7 +1110,7 @@ fbdevVideoSetupImageVideo (ScreenPtr pScreen)
        pAdaptor->GetPortAttribute     = FBDevVideoGetPortAttribute;
        pAdaptor->SetPortAttribute     = FBDevVideoSetPortAttribute;
        pAdaptor->QueryBestSize        = FBDevVideoQueryBestSize;
-       pAdaptor->QueryImageAttributes = fbdevVideoQueryImageAttributes;
+       pAdaptor->QueryImageAttributes = FBDEVVideoQueryImageAttributes;
 
        return pAdaptor;
 }
index 5e13562..2608e77 100644 (file)
@@ -58,6 +58,9 @@ typedef struct
        int   v4l2_index;
        void *v4l2_handle;
 
+    void *aligned_buffer;
+    int   aligned_width;
+
        int need_streamon;
 } FBDevPortPriv, *FBDevPortPrivPtr;
 
@@ -68,7 +71,8 @@ int fbdevVideoQueryImageAttributes (ScrnInfoPtr pScrnInfo,
                                     unsigned short *w,
                                     unsigned short *h,
                                     int            *pitches,
-                                    int            *offsets);
+                                    int            *offsets,
+                                    int            *lengths);
 
 void fbdevVideoSetOffset (ScrnInfoPtr pScrnInfo, int x, int y);
 void fbdevVideoGetV4l2Handles (ScrnInfoPtr pScrnInfo, void ***handles, int *cnt);
index 3fa2a95..2d16e34 100644 (file)
@@ -105,6 +105,9 @@ typedef struct
        int offset_y;
 
        int re_setting;
+
+    void *aligned_buffer;
+    int   aligned_width;
 } FBDevDispHandle;
 
 enum
@@ -397,6 +400,13 @@ _fbdevVideoV4l2CloseDevice (FBDevDispHandle *hdisp)
                hdisp->video_fd = -1;
        }
 
+    if (hdisp->aligned_buffer)
+    {
+        free (hdisp->aligned_buffer);
+        hdisp->aligned_buffer = NULL;
+        hdisp->aligned_width = 0;
+    }
+
        device_infos[hdisp->index].bOpened = FALSE;
 }
 
@@ -502,7 +512,7 @@ fbdevVideoV4l2StreamOn (void *handle)
                size = fbdevVideoQueryImageAttributes (NULL, FOURCC_RGB32,
                                                       (unsigned short*)&hdisp->status.dst.width,
                                                       (unsigned short*)&hdisp->status.dst.height,
-                                                      NULL, NULL);
+                                                      NULL, NULL, NULL);
 
                memcpy (hdisp->dst_buf[0].buf, hdisp->status.backup, size);
 
@@ -537,7 +547,7 @@ fbdevVideoV4l2StreamOff (void *handle)
                size = fbdevVideoQueryImageAttributes (NULL, FOURCC_RGB32,
                                                       (unsigned short*)&hdisp->status.dst.width,
                                                       (unsigned short*)&hdisp->status.dst.height,
-                                                      NULL, NULL);
+                                                      NULL, NULL, NULL);
 
                if (size > 0)
                        hdisp->status.backup = malloc (size);
@@ -736,6 +746,42 @@ fbdevVideoV4l2Draw (void *handle, uchar *buf, uint *phy_addrs)
                break;
        }
 
+    if (src_format == PIXMAN_yv12 && img.width % 16)
+    {
+        int src_p[3] = {0,}, src_o[3] = {0,}, src_l[3] = {0,};
+        int dst_p[3] = {0,}, dst_o[3] = {0,}, dst_l[3] = {0,};
+        unsigned short src_w, src_h, dst_w, dst_h;
+        int size;
+
+        src_w = img.width;
+        src_h = img.height;
+        fbdevVideoQueryImageAttributes (NULL, FOURCC_I420, &src_w, &src_h,
+                                        src_p, src_o, src_l);
+
+        dst_w = (img.width + 15) & ~15;
+        dst_h = img.height;
+        size = fbdevVideoQueryImageAttributes (NULL, FOURCC_I420, &dst_w, &dst_h,
+                                               dst_p, dst_o, dst_l);
+
+        if (!hdisp->aligned_buffer)
+        {
+            hdisp->aligned_buffer = malloc (size);
+            if (!hdisp->aligned_buffer)
+                return FALSE;
+        }
+
+        fbdev_util_copy_image (src_w, src_h,
+                               (char*)buf, src_w, src_h,
+                               src_p, src_o, src_l,
+                               (char*)hdisp->aligned_buffer, dst_w, dst_h,
+                               dst_p, dst_o, dst_l,
+                               3, 2, 2);
+
+        hdisp->aligned_width = dst_w;
+        img.width = dst_w;
+        buf = hdisp->aligned_buffer;
+    }
+
        /* support only RGB  */
        fbdev_pixman_convert_image (PIXMAN_OP_SRC,
                                    buf, hdisp->dst_buf[0].buf,