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