Zebediah Figura : qcap: Require libv4l2 to perform pixel format translation.

Alexandre Julliard julliard at winehq.org
Wed Apr 10 15:19:58 CDT 2019


Module: wine
Branch: master
Commit: 0423d5e65a6c7094d829d2a215fcf6a44bf57714
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=0423d5e65a6c7094d829d2a215fcf6a44bf57714

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Wed Apr 10 09:46:27 2019 -0500

qcap: Require libv4l2 to perform pixel format translation.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/qcap/v4l.c | 165 +++++++-------------------------------------------------
 1 file changed, 20 insertions(+), 145 deletions(-)

diff --git a/dlls/qcap/v4l.c b/dlls/qcap/v4l.c
index 04f9718..ce322d0 100644
--- a/dlls/qcap/v4l.c
+++ b/dlls/qcap/v4l.c
@@ -94,8 +94,6 @@ static BOOL video_init(void)
 #endif
 }
 
-typedef void (* Renderer)(const Capture *, LPBYTE bufferin, const BYTE *stream);
-
 struct _Capture
 {
     UINT width, height, bitDepth, fps, outputwidth, outputheight;
@@ -107,36 +105,10 @@ struct _Capture
     int fd, mmap;
     BOOL iscommitted, stopped;
 
-    __u32 pixelformat;
-    int depth;
-
     int image_size;
     unsigned char *image_data;
 
     HANDLE thread;
-    Renderer renderer;
-};
-
-static void renderer_RGB(const Capture *capBox, LPBYTE bufferin, const BYTE *stream);
-static void renderer_YUV(const Capture *capBox, LPBYTE bufferin, const BYTE *stream);
-
-static const struct
-{
-    int depth;
-    __u32 pixelformat;
-    Renderer renderer;
-}
-renderlist_V4l[] =
-{
-    {24, V4L2_PIX_FMT_BGR24, renderer_RGB},
-    {32, V4L2_PIX_FMT_BGR32, renderer_RGB},
-    {16, V4L2_PIX_FMT_YUYV, renderer_YUV},
-    {16, V4L2_PIX_FMT_UYVY, renderer_YUV},
-    {12, V4L2_PIX_FMT_Y41P, renderer_YUV},
-    {16, V4L2_PIX_FMT_YUV422P, renderer_YUV},
-    {12, V4L2_PIX_FMT_YUV411P, renderer_YUV},
-    {12, V4L2_PIX_FMT_YUV420, renderer_YUV},
-    {10, V4L2_PIX_FMT_YUV410, renderer_YUV},
 };
 
 static int xioctl(int fd, int request, void * arg)
@@ -153,7 +125,7 @@ static int xioctl(int fd, int request, void * arg)
 /* Prepare the capture buffers */
 static HRESULT V4l_Prepare(Capture *device)
 {
-    device->image_size = device->depth * device->height * device->width / 8;
+    device->image_size = device->height * device->width * 3;
     if (!(device->image_data = heap_alloc(device->image_size)))
         return E_OUTOFMEMORY;
     return S_OK;
@@ -347,70 +319,6 @@ HRESULT qcap_driver_set_prop(Capture *device, VideoProcAmpProperty property,
     return S_OK;
 }
 
-static void renderer_RGB(const Capture *device, BYTE *bufferin, const BYTE *stream)
-{
-    int size = device->height * device->width * device->depth / 8;
-    int pointer, offset;
-
-    switch (device->pixelformat)
-    {
-    case V4L2_PIX_FMT_BGR24:
-        memcpy(bufferin, stream, size);
-        break;
-    case V4L2_PIX_FMT_BGR32:
-        pointer = 0;
-        offset = 1;
-        while (pointer + offset <= size)
-        {
-            bufferin[pointer] = stream[pointer + offset];
-            pointer++;
-            bufferin[pointer] = stream[pointer + offset];
-            pointer++;
-            bufferin[pointer] = stream[pointer + offset];
-            pointer++;
-            offset++;
-        }
-        break;
-    default:
-        FIXME("Unhandled pixel format %#x.\n", device->pixelformat);
-        return;
-    }
-}
-
-static void renderer_YUV(const Capture *device, BYTE *bufferin, const BYTE *stream)
-{
-    enum YUV_Format format;
-
-    switch (device->pixelformat)
-    {
-    case V4L2_PIX_FMT_YUYV:
-        format = YUYV;
-        break;
-    case V4L2_PIX_FMT_UYVY:
-        format = UYVY;
-        break;
-    case V4L2_PIX_FMT_Y41P:
-        format = UYYVYY;
-        break;
-    case V4L2_PIX_FMT_YUV422P:
-        format = YUVP_421;
-        break;
-    case V4L2_PIX_FMT_YUV411P:
-        format = YUVP_441;
-        break;
-    case V4L2_PIX_FMT_YUV420:
-        format = YUVP_422;
-        break;
-    case V4L2_PIX_FMT_YUV410:
-        format = YUVP_444;
-        break;
-    default:
-        FIXME("Unhandled pixel format %#x.\n", device->pixelformat);
-        return;
-    }
-    YUV_To_RGB24(format, bufferin, stream, device->width, device->height);
-}
-
 static void Resize(const Capture * capBox, LPBYTE output, const BYTE *input)
 {
     /* the whole image needs to be reversed,
@@ -522,7 +430,7 @@ static DWORD WINAPI ReadThread(LPVOID lParam)
             IMediaSample_GetPointer(pSample, &pTarget);
             /* FIXME: Check return values.. */
             V4l_GetFrame(capBox, &pInput);
-            capBox->renderer(capBox, pOutput, pInput);
+            memcpy(pOutput, pInput, len);
             Resize(capBox, pTarget, pOutput);
             hr = BaseOutputPinImpl_Deliver((BaseOutputPin *)capBox->pOut, pSample);
             TRACE("%p -> Frame %u: %x\n", capBox, ++framecount, hr);
@@ -659,57 +567,10 @@ HRESULT qcap_driver_stop(Capture *capBox, FILTER_STATE *state)
     return S_OK;
 }
 
-static int negotiate_format(Capture *device)
-{
-    struct v4l2_format format = {0};
-    int fd = device->fd;
-    unsigned int i;
-
-    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-    if (xioctl(fd, VIDIOC_G_FMT, &format) == -1)
-    {
-        ERR("Failed to get device format: %s\n", strerror(errno));
-        return -1;
-    }
-
-    for (i = 0; i < ARRAY_SIZE(renderlist_V4l); ++i)
-    {
-        if (renderlist_V4l[i].pixelformat == format.fmt.pix.pixelformat)
-        {
-            TRACE("Using device-reported format %#x.\n", format.fmt.pix.pixelformat);
-            device->depth = renderlist_V4l[i].depth;
-            device->renderer = renderlist_V4l[i].renderer;
-            device->pixelformat = format.fmt.pix.pixelformat;
-            device->width = format.fmt.pix.width;
-            device->height = format.fmt.pix.height;
-            return 0;
-        }
-    }
-
-    for (i = 0; i < ARRAY_SIZE(renderlist_V4l); ++i)
-    {
-        format.fmt.pix.pixelformat = renderlist_V4l[i].pixelformat;
-        if (!xioctl(fd, VIDIOC_S_FMT, &format)
-                && format.fmt.pix.pixelformat == renderlist_V4l[i].pixelformat)
-        {
-            TRACE("Using format %#x.\n", format.fmt.pix.pixelformat);
-            device->depth = renderlist_V4l[i].depth;
-            device->renderer = renderlist_V4l[i].renderer;
-            device->pixelformat = format.fmt.pix.pixelformat;
-            device->width = format.fmt.pix.width;
-            device->height = format.fmt.pix.height;
-            return 0;
-        }
-    }
-
-    FIXME("Could not negotiate an acceptable format.\n");
-    return -1;
-}
-
 Capture * qcap_driver_init( IPin *pOut, USHORT card )
 {
     struct v4l2_capability caps = {{0}};
+    struct v4l2_format format = {0};
     Capture *device = NULL;
     BOOL have_libv4l2;
     char path[20];
@@ -762,11 +623,25 @@ Capture * qcap_driver_init( IPin *pOut, USHORT card )
         goto error;
     }
 
-    if (negotiate_format(device) == -1)
+    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    if (xioctl(fd, VIDIOC_G_FMT, &format) == -1)
+    {
+        ERR("Failed to get device format: %s\n", strerror(errno));
+        goto error;
+    }
+
+    format.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;
+    if (xioctl(fd, VIDIOC_S_FMT, &format) == -1
+            || format.fmt.pix.pixelformat != V4L2_PIX_FMT_BGR24)
+    {
+        ERR("Failed to set pixel format: %s\n", strerror(errno));
+        if (!have_libv4l2)
+            ERR_(winediag)("You may need libv4l2 to use this device.\n");
         goto error;
+    }
 
-    device->outputwidth = device->width;
-    device->outputheight = device->height;
+    device->outputwidth = device->width = format.fmt.pix.width;
+    device->outputheight = device->height = format.fmt.pix.height;
     device->swresize = FALSE;
     device->bitDepth = 24;
     device->pOut = pOut;




More information about the wine-cvs mailing list