Signed-off-by: Zebediah Figura z.figura12@gmail.com --- 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 1b10e503c9..5f199f4af9 100644 --- a/dlls/qcap/v4l.c +++ b/dlls/qcap/v4l.c @@ -91,8 +91,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; @@ -104,36 +102,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) @@ -150,7 +122,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; @@ -344,70 +316,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, @@ -519,7 +427,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); @@ -656,57 +564,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]; @@ -759,11 +620,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;