ReactOS 0.4.17-dev-966-gf06eace
v4l.c
Go to the documentation of this file.
1/*
2 * v4l2 backend to the VFW Capture filter
3 *
4 * Copyright 2005 Maarten Lankhorst
5 * Copyright 2019 Zebediah Figura
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#if 0
23#pragma makedep unix
24#endif
25
26#define BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD /* work around ioctl breakage on Android */
27
28#include "config.h"
29
30#include <stdarg.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <fcntl.h>
34#ifndef __REACTOS__
35#include <dlfcn.h>
36#endif
37#include <sys/ioctl.h>
38#ifndef __REACTOS__
39#include <sys/mman.h>
40#endif
41#include <errno.h>
42#include <sys/time.h>
43#ifdef HAVE_ASM_TYPES_H
44#include <asm/types.h>
45#endif
46#ifdef HAVE_LINUX_VIDEODEV2_H
47#include <linux/videodev2.h>
48#endif
49#include <unistd.h>
50
51#include "ntstatus.h"
52#define WIN32_NO_STATUS
53#include "initguid.h"
54#include "qcap_private.h"
55#include "winternl.h"
56
57#ifdef HAVE_LINUX_VIDEODEV2_H
58
61
62static typeof(open) *video_open = open;
63static typeof(close) *video_close = close;
64static typeof(ioctl) *video_ioctl = ioctl;
65static typeof(read) *video_read = read;
66
67static BOOL video_init(void)
68{
69#ifdef SONAME_LIBV4L2
70 static void *video_lib;
71
72 if (video_lib)
73 return TRUE;
74 if (!(video_lib = dlopen(SONAME_LIBV4L2, RTLD_NOW)))
75 return FALSE;
76 video_open = dlsym(video_lib, "v4l2_open");
77 video_close = dlsym(video_lib, "v4l2_close");
78 video_ioctl = dlsym(video_lib, "v4l2_ioctl");
79 video_read = dlsym(video_lib, "v4l2_read");
80
81 return TRUE;
82#else
83 return FALSE;
84#endif
85}
86
87struct caps
88{
90 AM_MEDIA_TYPE media_type;
91 VIDEOINFOHEADER video_info;
92 VIDEO_STREAM_CONFIG_CAPS config;
93};
94
95struct video_capture_device
96{
97 const struct caps *current_caps;
98 struct caps *caps;
99 LONG caps_count;
100 struct v4l2_format device_format;
101 BOOL started;
102
103 int image_size, image_pitch;
104 BYTE *image_data;
105
106 int fd, mmap;
107};
108
109static int xioctl(int fd, int request, void * arg)
110{
111 int r;
112
113 do {
114 r = video_ioctl (fd, request, arg);
115 } while (-1 == r && EINTR == errno);
116
117 return r;
118}
119
120static struct video_capture_device *get_device( video_capture_device_t dev )
121{
122 return (struct video_capture_device *)(ULONG_PTR)dev;
123}
124
125static void device_destroy(struct video_capture_device *device)
126{
127 if (device->fd != -1)
128 video_close(device->fd);
129 if (device->caps_count)
130 free(device->caps);
131 free(device->image_data);
132 free(device);
133}
134
135static const struct caps *find_caps(struct video_capture_device *device, const AM_MEDIA_TYPE *mt)
136{
137 const VIDEOINFOHEADER *video_info = (VIDEOINFOHEADER *)mt->pbFormat;
138 LONG index;
139
140 if (mt->cbFormat < sizeof(VIDEOINFOHEADER) || !video_info)
141 return NULL;
142
143 for (index = 0; index < device->caps_count; index++)
144 {
145 struct caps *caps = &device->caps[index];
146
147 if (IsEqualGUID(&mt->formattype, &caps->media_type.formattype)
148 && video_info->bmiHeader.biWidth == caps->video_info.bmiHeader.biWidth
149 && video_info->bmiHeader.biHeight == caps->video_info.bmiHeader.biHeight)
150 return caps;
151 }
152 return NULL;
153}
154
155static NTSTATUS v4l_device_check_format( void *args )
156{
157 const struct check_format_params *params = args;
158 struct video_capture_device *device = get_device(params->device);
159
160 TRACE("device %p, mt %p.\n", device, params->mt);
161
162 if (!IsEqualGUID(&params->mt->majortype, &MEDIATYPE_Video))
163 return E_FAIL;
164
165 if (find_caps(device, params->mt))
166 return S_OK;
167
168 return E_FAIL;
169}
170
171static HRESULT set_caps(struct video_capture_device *device, const struct caps *caps, BOOL try)
172{
173 struct v4l2_format format = {0};
175 BYTE *image_data;
176
177 width = caps->video_info.bmiHeader.biWidth;
178 height = caps->video_info.bmiHeader.biHeight;
179 image_size = width * height * caps->video_info.bmiHeader.biBitCount / 8;
180
181 if (!(image_data = malloc(image_size)))
182 {
183 ERR("Failed to allocate memory.\n");
184 return E_OUTOFMEMORY;
185 }
186
187 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
188 format.fmt.pix.pixelformat = caps->pixelformat;
189 format.fmt.pix.width = width;
190 format.fmt.pix.height = height;
191 if (xioctl(device->fd, try ? VIDIOC_TRY_FMT : VIDIOC_S_FMT, &format) == -1
192 || format.fmt.pix.pixelformat != caps->pixelformat
193 || format.fmt.pix.width != width
194 || format.fmt.pix.height != height)
195 {
196 ERR("Failed to set pixel format: %s.\n", strerror(errno));
197 free(image_data);
199 }
200
201 device->started = !try;
202 device->device_format = format;
203 device->current_caps = caps;
204 device->image_size = image_size;
205 device->image_pitch = width * caps->video_info.bmiHeader.biBitCount / 8;
206 free(device->image_data);
207 device->image_data = image_data;
208 return S_OK;
209}
210
211static NTSTATUS v4l_device_set_format( void *args )
212{
213 const struct set_format_params *params = args;
214 struct video_capture_device *device = get_device(params->device);
215 const struct caps *caps;
216
217 caps = find_caps(device, params->mt);
218 if (!caps)
219 return E_FAIL;
220
221 if (device->current_caps == caps)
222 return S_OK;
223
224 return set_caps(device, caps, FALSE);
225}
226
227static NTSTATUS v4l_device_get_format( void *args )
228{
229 const struct get_format_params *params = args;
230 struct video_capture_device *device = get_device(params->device);
231
232 *params->mt = device->current_caps->media_type;
233 *params->format = device->current_caps->video_info;
234 return S_OK;
235}
236
237static NTSTATUS v4l_device_get_media_type( void *args )
238{
239 const struct get_media_type_params *params = args;
240 struct video_capture_device *device = get_device(params->device);
241 unsigned int caps_count = (device->current_caps) ? 1 : device->caps_count;
242
243 if (params->index >= caps_count)
244 return VFW_S_NO_MORE_ITEMS;
245
246 if (device->current_caps)
247 {
248 *params->mt = device->current_caps->media_type;
249 *params->format = device->current_caps->video_info;
250 }
251 else
252 {
253 *params->mt = device->caps[params->index].media_type;
254 *params->format = device->caps[params->index].video_info;
255 }
256 return S_OK;
257}
258
259static __u32 v4l2_cid_from_qcap_property(VideoProcAmpProperty property)
260{
261 switch (property)
262 {
263 case VideoProcAmp_Brightness:
264 return V4L2_CID_BRIGHTNESS;
266 return V4L2_CID_CONTRAST;
267 case VideoProcAmp_Hue:
268 return V4L2_CID_HUE;
270 return V4L2_CID_SATURATION;
271 default:
272 FIXME("Unhandled property %d.\n", property);
273 return 0;
274 }
275}
276
277static NTSTATUS v4l_device_get_prop_range( void *args )
278{
279 const struct get_prop_range_params *params = args;
280 struct video_capture_device *device = get_device(params->device);
281 struct v4l2_queryctrl ctrl;
282
283 ctrl.id = v4l2_cid_from_qcap_property(params->property);
284
285 if (xioctl(device->fd, VIDIOC_QUERYCTRL, &ctrl) == -1)
286 {
287 WARN("Failed to query control: %s\n", strerror(errno));
289 }
290
291 *params->min = ctrl.minimum;
292 *params->max = ctrl.maximum;
293 *params->step = ctrl.step;
294 *params->default_value = ctrl.default_value;
296 return S_OK;
297}
298
299static NTSTATUS v4l_device_get_prop( void *args )
300{
301 const struct get_prop_params *params = args;
302 struct video_capture_device *device = get_device(params->device);
303 struct v4l2_control ctrl;
304
305 ctrl.id = v4l2_cid_from_qcap_property(params->property);
306
307 if (xioctl(device->fd, VIDIOC_G_CTRL, &ctrl) == -1)
308 {
309 WARN("Failed to get property: %s\n", strerror(errno));
310 return E_FAIL;
311 }
312
315
316 return S_OK;
317}
318
319static NTSTATUS v4l_device_set_prop( void *args )
320{
321 const struct set_prop_params *params = args;
322 struct video_capture_device *device = get_device(params->device);
323 struct v4l2_control ctrl;
324
325 ctrl.id = v4l2_cid_from_qcap_property(params->property);
326 ctrl.value = params->value;
327
328 if (xioctl(device->fd, VIDIOC_S_CTRL, &ctrl) == -1)
329 {
330 WARN("Failed to set property: %s\n", strerror(errno));
331 return E_FAIL;
332 }
333
334 return S_OK;
335}
336
337static void reverse_image(struct video_capture_device *device, LPBYTE output, const BYTE *input)
338{
339 int inoffset, outoffset, pitch;
340
341 /* the whole image needs to be reversed,
342 because the dibs are messed up in windows */
343 outoffset = device->image_size;
344 pitch = device->image_pitch;
345 inoffset = 0;
346 while (outoffset > 0)
347 {
348 int x;
349 outoffset -= pitch;
350 for (x = 0; x < pitch; x++)
351 output[outoffset + x] = input[inoffset + x];
352 inoffset += pitch;
353 }
354}
355
356static NTSTATUS v4l_device_read_frame( void *args )
357{
358 const struct read_frame_params *params = args;
359 struct video_capture_device *device = get_device(params->device);
360
361 while (video_read(device->fd, device->image_data, device->image_size) < 0)
362 {
363 if (errno != EAGAIN)
364 {
365 ERR("Failed to read frame: %s\n", strerror(errno));
366 return FALSE;
367 }
368 }
369
370 reverse_image(device, params->data, device->image_data);
371 return TRUE;
372}
373
374static void fill_caps(__u32 pixelformat, __u32 width, __u32 height,
375 __u32 max_fps, __u32 min_fps, struct caps *caps)
376{
377 LONG depth = 24;
378
379 memset(caps, 0, sizeof(*caps));
380 caps->video_info.dwBitRate = width * height * depth * max_fps;
381 caps->video_info.bmiHeader.biSize = sizeof(caps->video_info.bmiHeader);
382 caps->video_info.bmiHeader.biWidth = width;
383 caps->video_info.bmiHeader.biHeight = height;
384 caps->video_info.bmiHeader.biPlanes = 1;
385 caps->video_info.bmiHeader.biBitCount = depth;
386 caps->video_info.bmiHeader.biCompression = BI_RGB;
387 caps->video_info.bmiHeader.biSizeImage = width * height * depth / 8;
388 caps->media_type.majortype = MEDIATYPE_Video;
389 caps->media_type.subtype = MEDIASUBTYPE_RGB24;
390 caps->media_type.bFixedSizeSamples = TRUE;
391 caps->media_type.bTemporalCompression = FALSE;
392 caps->media_type.lSampleSize = width * height * depth / 8;
393 caps->media_type.formattype = FORMAT_VideoInfo;
394 caps->media_type.pUnk = NULL;
395 caps->media_type.cbFormat = sizeof(VIDEOINFOHEADER);
396 /* We reallocate the caps array, so pbFormat has to be set after all caps
397 * have been enumerated. */
398 caps->config.MaxFrameInterval = 10000000 / max_fps;
399 caps->config.MinFrameInterval = 10000000 / min_fps;
400 caps->config.MaxOutputSize.cx = width;
401 caps->config.MaxOutputSize.cy = height;
402 caps->config.MinOutputSize.cx = width;
403 caps->config.MinOutputSize.cy = height;
404 caps->config.guid = FORMAT_VideoInfo;
405 caps->config.MinBitsPerSecond = width * height * depth * min_fps;
406 caps->config.MaxBitsPerSecond = width * height * depth * max_fps;
407 caps->pixelformat = pixelformat;
408}
409
410static NTSTATUS v4l_device_get_caps( void *args )
411{
412 const struct get_caps_params *params = args;
413 struct video_capture_device *device = get_device(params->device);
414
415 *params->caps = device->caps[params->index].config;
416 *params->mt = device->caps[params->index].media_type;
417 *params->format = device->caps[params->index].video_info;
418 return S_OK;
419}
420
421static NTSTATUS v4l_device_get_caps_count( void *args )
422{
423 const struct get_caps_count_params *params = args;
424 struct video_capture_device *device = get_device(params->device);
425
426 *params->count = device->caps_count;
427 return S_OK;
428}
429
430static NTSTATUS v4l_device_create( void *args )
431{
432 const struct create_params *params = args;
433 struct v4l2_frmsizeenum frmsize = {0};
434 struct video_capture_device *device;
435 struct v4l2_capability caps = {{0}};
436 struct v4l2_format format = {0};
437 BOOL have_libv4l2;
438 char path[20];
439 HRESULT hr;
440 int fd, i;
441
442 have_libv4l2 = video_init();
443
444 if (!(device = calloc(1, sizeof(*device))))
445 return E_OUTOFMEMORY;
446
447 sprintf(path, "/dev/video%i", params->index);
448 TRACE("Opening device %s.\n", path);
449#ifdef O_CLOEXEC
450 if ((fd = video_open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC)) == -1 && errno == EINVAL)
451#endif
452 fd = video_open(path, O_RDWR | O_NONBLOCK);
453 if (fd == -1)
454 {
455 WARN("Failed to open video device: %s\n", strerror(errno));
456 goto error;
457 }
458 fcntl(fd, F_SETFD, FD_CLOEXEC); /* in case O_CLOEXEC isn't supported */
459 device->fd = fd;
460
461 if (xioctl(fd, VIDIOC_QUERYCAP, &caps) == -1)
462 {
463 WARN("Failed to query device capabilities: %s\n", strerror(errno));
464 goto error;
465 }
466
467#ifdef V4L2_CAP_DEVICE_CAPS
468 if (caps.capabilities & V4L2_CAP_DEVICE_CAPS)
469 caps.capabilities = caps.device_caps;
470#endif
471
472 if (!(caps.capabilities & V4L2_CAP_VIDEO_CAPTURE))
473 {
474 WARN("Device does not support single-planar video capture.\n");
475 goto error;
476 }
477
478 if (!(caps.capabilities & V4L2_CAP_READWRITE))
479 {
480 WARN("Device does not support read().\n");
481 if (!have_libv4l2)
482#ifdef SONAME_LIBV4L2
483 ERR_(winediag)("Reading from %s requires libv4l2, but it could not be loaded.\n", path);
484#else
485 ERR_(winediag)("Reading from %s requires libv4l2, but Wine was compiled without libv4l2 support.\n", path);
486#endif
487 goto error;
488 }
489
490 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
491 if (xioctl(fd, VIDIOC_G_FMT, &format) == -1)
492 {
493 ERR("Failed to get device format: %s\n", strerror(errno));
494 goto error;
495 }
496
497 format.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;
498 if (xioctl(fd, VIDIOC_TRY_FMT, &format) == -1
499 || format.fmt.pix.pixelformat != V4L2_PIX_FMT_BGR24)
500 {
501 ERR("This device doesn't support V4L2_PIX_FMT_BGR24 format.\n");
502 goto error;
503 }
504
505 frmsize.pixel_format = V4L2_PIX_FMT_BGR24;
506 while (xioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) != -1)
507 {
508 struct v4l2_frmivalenum frmival = {0};
509 __u32 max_fps = 30, min_fps = 30;
510 struct caps *new_caps;
511
512 frmival.pixel_format = format.fmt.pix.pixelformat;
513 if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE)
514 {
515 frmival.width = frmsize.discrete.width;
516 frmival.height = frmsize.discrete.height;
517 }
518 else if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE)
519 {
520 frmival.width = frmsize.stepwise.max_width;
521 frmival.height = frmsize.stepwise.min_height;
522 }
523 else
524 {
525 FIXME("Unhandled frame size type: %d.\n", frmsize.type);
526 continue;
527 }
528
529 if (xioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival) != -1)
530 {
531 if (frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE)
532 {
533 max_fps = frmival.discrete.denominator / frmival.discrete.numerator;
534 min_fps = max_fps;
535 }
536 else if (frmival.type == V4L2_FRMIVAL_TYPE_STEPWISE
537 || frmival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS)
538 {
539 min_fps = frmival.stepwise.max.denominator / frmival.stepwise.max.numerator;
540 max_fps = frmival.stepwise.min.denominator / frmival.stepwise.min.numerator;
541 }
542 }
543 else
544 ERR("Failed to get fps: %s.\n", strerror(errno));
545
546 new_caps = realloc(device->caps, (device->caps_count + 1) * sizeof(*device->caps));
547 if (!new_caps)
548 goto error;
549 device->caps = new_caps;
550 fill_caps(format.fmt.pix.pixelformat, frmsize.discrete.width, frmsize.discrete.height,
551 max_fps, min_fps, &device->caps[device->caps_count]);
552 device->caps_count++;
553
554 frmsize.index++;
555 }
556
557 /* We reallocate the caps array, so we have to delay setting pbFormat. */
558 for (i = 0; i < device->caps_count; ++i)
559 device->caps[i].media_type.pbFormat = (BYTE *)&device->caps[i].video_info;
560
561 if (FAILED(hr = set_caps(device, &device->caps[0], TRUE)))
562 {
563 if (hr == VFW_E_TYPE_NOT_ACCEPTED && !have_libv4l2)
564 ERR_(winediag)("You may need libv4l2 to use this device.\n");
565 goto error;
566 }
567
568 TRACE("Format: %d bpp - %dx%d.\n", device->current_caps->video_info.bmiHeader.biBitCount,
569 (int)device->current_caps->video_info.bmiHeader.biWidth,
570 (int)device->current_caps->video_info.bmiHeader.biHeight);
571
572 *params->device = (ULONG_PTR)device;
573 return S_OK;
574
575error:
576 device_destroy(device);
577 return E_FAIL;
578}
579
580static NTSTATUS v4l_device_start( void *args )
581{
582 const struct start_params *params = args;
583 struct video_capture_device *device = get_device(params->device);
584
585 if (device->started) return S_OK;
586
587 if (xioctl(device->fd, VIDIOC_S_FMT, &device->device_format) == -1)
588 {
589 ERR("Failed to set pixel format: %s.\n", strerror(errno));
591 }
592 device->started = TRUE;
593 return S_OK;
594}
595
596static NTSTATUS v4l_device_destroy( void *args )
597{
598 const struct destroy_params *params = args;
599
600 device_destroy( get_device(params->device) );
601 return S_OK;
602}
603
604const unixlib_entry_t __wine_unix_call_funcs[] =
605{
606 v4l_device_create,
607 v4l_device_start,
608 v4l_device_destroy,
609 v4l_device_check_format,
610 v4l_device_set_format,
611 v4l_device_get_format,
612 v4l_device_get_media_type,
613 v4l_device_get_caps,
614 v4l_device_get_caps_count,
615 v4l_device_get_prop_range,
616 v4l_device_get_prop,
617 v4l_device_set_prop,
618 v4l_device_read_frame,
619};
620
622
623#ifdef _WIN64
624
625typedef ULONG PTR32;
626
627struct am_media_type32
628{
629 GUID majortype;
631 BOOL bFixedSizeSamples;
632 BOOL bTemporalCompression;
633 ULONG lSampleSize;
634 GUID formattype;
635 PTR32 pUnk;
636 ULONG cbFormat;
637 PTR32 pbFormat;
638};
639
640static AM_MEDIA_TYPE *get_media_type( const struct am_media_type32 *mt32, AM_MEDIA_TYPE *mt )
641{
642 mt->majortype = mt32->majortype;
643 mt->subtype = mt32->subtype;
644 mt->bFixedSizeSamples = mt32->bFixedSizeSamples;
645 mt->bTemporalCompression = mt32->bTemporalCompression;
646 mt->lSampleSize = mt32->lSampleSize;
647 mt->formattype = mt32->formattype;
648 mt->pUnk = NULL;
649 mt->cbFormat = mt32->cbFormat;
650 mt->pbFormat = ULongToPtr(mt32->pbFormat);
651 return mt;
652}
653
654static void put_media_type( const AM_MEDIA_TYPE *mt, struct am_media_type32 *mt32 )
655{
656 mt32->majortype = mt->majortype;
657 mt32->subtype = mt->subtype;
658 mt32->bFixedSizeSamples = mt->bFixedSizeSamples;
659 mt32->bTemporalCompression = mt->bTemporalCompression;
660 mt32->lSampleSize = mt->lSampleSize;
661 mt32->formattype = mt->formattype;
662}
663
664static NTSTATUS wow64_v4l_device_create( void *args )
665{
666 struct
667 {
668 unsigned int index;
669 PTR32 device;
670 } const *params32 = args;
671
672 struct create_params params =
673 {
674 params32->index,
675 ULongToPtr(params32->device)
676 };
677
678 return v4l_device_create( &params );
679}
680
681static NTSTATUS wow64_v4l_device_check_format( void *args )
682{
683 struct
684 {
686 PTR32 mt;
687 } const *params32 = args;
688
689 AM_MEDIA_TYPE mt;
691 {
692 params32->device,
693 get_media_type( ULongToPtr(params32->mt), &mt )
694 };
695
696 return v4l_device_check_format( &params );
697}
698
699static NTSTATUS wow64_v4l_device_set_format( void *args )
700{
701 struct
702 {
704 PTR32 mt;
705 } const *params32 = args;
706
709 {
710 params32->device,
711 get_media_type( ULongToPtr(params32->mt), &mt )
712 };
713
714 return v4l_device_set_format( &params );
715}
716
717static NTSTATUS wow64_v4l_device_get_format( void *args )
718{
719 struct
720 {
722 PTR32 mt;
723 PTR32 format;
724 } const *params32 = args;
725
728 {
729 params32->device,
730 &mt,
731 ULongToPtr(params32->format)
732 };
733
734 NTSTATUS status = v4l_device_get_format( &params );
735 if (!status) put_media_type( &mt, ULongToPtr(params32->mt) );
736 return status;
737}
738
739static NTSTATUS wow64_v4l_device_get_media_type( void *args )
740{
741 struct
742 {
744 unsigned int index;
745 PTR32 mt;
746 PTR32 format;
747 } const *params32 = args;
748
751 {
752 params32->device,
753 params32->index,
754 &mt,
755 ULongToPtr(params32->format)
756 };
757
758 NTSTATUS status = v4l_device_get_media_type( &params );
759 if (!status) put_media_type( &mt, ULongToPtr(params32->mt) );
760 return status;
761}
762
763static NTSTATUS wow64_v4l_device_get_caps( void *args )
764{
765 struct
766 {
768 unsigned int index;
769 PTR32 mt;
770 PTR32 format;
771 PTR32 caps;
772 } const *params32 = args;
773
775 struct get_caps_params params =
776 {
777 params32->device,
778 params32->index,
779 &mt,
780 ULongToPtr(params32->format),
781 ULongToPtr(params32->caps)
782 };
783
784 NTSTATUS status = v4l_device_get_caps( &params );
785 if (!status) put_media_type( &mt, ULongToPtr(params32->mt) );
786 return status;
787}
788
789static NTSTATUS wow64_v4l_device_get_caps_count( void *args )
790{
791 struct
792 {
794 PTR32 count;
795 } const *params32 = args;
796
798 {
799 params32->device,
800 ULongToPtr(params32->count)
801 };
802
803 return v4l_device_get_caps_count( &params );
804}
805
806static NTSTATUS wow64_v4l_device_get_prop_range( void *args )
807{
808 struct
809 {
812 PTR32 min;
813 PTR32 max;
814 PTR32 step;
815 PTR32 default_value;
816 PTR32 flags;
817 } const *params32 = args;
818
820 {
821 params32->device,
822 params32->property,
823 ULongToPtr(params32->min),
824 ULongToPtr(params32->max),
825 ULongToPtr(params32->step),
826 ULongToPtr(params32->default_value),
827 ULongToPtr(params32->flags)
828 };
829
830 return v4l_device_get_prop_range( &params );
831}
832
833static NTSTATUS wow64_v4l_device_get_prop( void *args )
834{
835 struct
836 {
839 PTR32 value;
840 PTR32 flags;
841 } const *params32 = args;
842
843 struct get_prop_params params =
844 {
845 params32->device,
846 params32->property,
847 ULongToPtr(params32->value),
848 ULongToPtr(params32->flags)
849 };
850
851 return v4l_device_get_prop( &params );
852}
853
854static NTSTATUS wow64_v4l_device_read_frame( void *args )
855{
856 struct
857 {
859 PTR32 data;
860 } const *params32 = args;
861
863 {
864 params32->device,
865 ULongToPtr(params32->data)
866 };
867
868 return v4l_device_read_frame( &params );
869}
870
871const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
872{
873 wow64_v4l_device_create,
874 v4l_device_start,
875 v4l_device_destroy,
876 wow64_v4l_device_check_format,
877 wow64_v4l_device_set_format,
878 wow64_v4l_device_get_format,
879 wow64_v4l_device_get_media_type,
880 wow64_v4l_device_get_caps,
881 wow64_v4l_device_get_caps_count,
882 wow64_v4l_device_get_prop_range,
883 wow64_v4l_device_get_prop,
884 v4l_device_set_prop,
885 wow64_v4l_device_read_frame,
886};
887
888C_ASSERT( ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_funcs_count );
889
890#endif /* _WIN64 */
891
892#endif /* HAVE_LINUX_VIDEODEV2_H */
#define read
Definition: acwin.h:97
#define close
Definition: acwin.h:99
enum VideoProcAmp_Hue
enum VideoProcAmp_Contrast
enum VideoProcAmp_Saturation
@ VideoProcAmp_Flags_Manual
Definition: axextend.idl:980
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
#define index(s, c)
Definition: various.h:29
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define ULongToPtr(ul)
Definition: basetsd.h:86
u32 __u32
Definition: btrfs.h:19
#define ARRAYSIZE(a)
Definition: cat.c:25
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
struct config_s config
HRESULT hr
Definition: delayimp.cpp:582
@ unix_funcs_count
Definition: unixlib.h:110
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
const unixlib_entry_t __wine_unix_call_funcs[]
Definition: freetype.c:804
BOOL get_media_type(const WCHAR *filename, GUID *majortype, GUID *subtype, GUID *source_clsid)
Definition: filesource.c:198
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
char *CDECL strerror(int err)
Definition: errno.c:273
#define EINVAL
Definition: errno.h:44
#define EINTR
Definition: errno.h:27
#define EBUSY
Definition: errno.h:38
#define errno
Definition: errno.h:120
#define EAGAIN
Definition: errno.h:34
#define O_RDWR
Definition: fcntl.h:36
#define open
Definition: io.h:44
pixelformat
Definition: converter.c:37
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:41
#define ULONG_PTR
Definition: config.h:101
struct tagVIDEOINFOHEADER VIDEOINFOHEADER
unsigned int BOOL
Definition: ntddk_ex.h:94
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint index
Definition: glext.h:6031
GLenum const GLfloat * params
Definition: glext.h:5645
GLbitfield flags
Definition: glext.h:7161
GLenum GLenum GLenum input
Definition: glext.h:9031
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define C_ASSERT(e)
Definition: intsafe.h:73
if(dx< 0)
Definition: linetemp.h:194
static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
Definition: mipmap.c:4858
#define error(str)
Definition: mkdosfs.c:1605
#define sprintf
Definition: sprintf.c:45
static HANDLE get_device(USHORT page, USHORT usages[], UINT usage_count, DWORD access)
Definition: device.c:106
#define ctrl
Definition: input.c:3281
#define O_NONBLOCK
Definition: port.h:158
#define RTLD_NOW
Definition: port.h:100
#define min(a, b)
Definition: monoChain.cc:55
const GUID * subtype
Definition: mpegvideo.c:120
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
UINT64 video_capture_device_t
Definition: qcap_private.h:46
#define calloc
Definition: rosglue.h:14
#define ERR_(ch,...)
Definition: debug.h:156
static int fd
Definition: io.c:51
#define memset(x, y, z)
Definition: compat.h:39
#define FD_CLOEXEC
Definition: fcntl.h:102
#define args
Definition: format.c:66
#define TRACE(s)
Definition: solgame.cpp:4
Definition: match.c:390
video_capture_device_t device
Definition: qcap_private.h:66
const AM_MEDIA_TYPE * mt
Definition: qcap_private.h:67
unsigned int index
Definition: qcap_private.h:50
video_capture_device_t * device
Definition: qcap_private.h:51
char * value
Definition: wpp.c:53
Definition: devices.h:37
DWORD width
Definition: ddrawstream.c:34
DWORD height
Definition: ddrawstream.c:35
video_capture_device_t device
Definition: qcap_private.h:102
video_capture_device_t device
Definition: qcap_private.h:93
AM_MEDIA_TYPE * mt
Definition: qcap_private.h:95
VIDEOINFOHEADER * format
Definition: qcap_private.h:80
AM_MEDIA_TYPE * mt
Definition: qcap_private.h:79
video_capture_device_t device
Definition: qcap_private.h:78
VIDEOINFOHEADER * format
Definition: qcap_private.h:88
AM_MEDIA_TYPE * mt
Definition: qcap_private.h:87
video_capture_device_t device
Definition: qcap_private.h:85
video_capture_device_t device
Definition: qcap_private.h:119
VideoProcAmpProperty property
Definition: qcap_private.h:109
video_capture_device_t device
Definition: qcap_private.h:108
video_capture_device_t device
Definition: qcap_private.h:135
Definition: tftpd.h:86
video_capture_device_t device
Definition: qcap_private.h:72
const AM_MEDIA_TYPE * mt
Definition: qcap_private.h:73
Definition: ps.c:97
BITMAPINFOHEADER bmiHeader
Definition: amvideo.idl:189
#define max(a, b)
Definition: svc.c:63
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define BI_RGB
Definition: uefivid.c:46
Definition: pdh_main.c:64
#define E_PROP_ID_UNSUPPORTED
Definition: vfwmsgs.h:173
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81
#define VFW_S_NO_MORE_ITEMS
Definition: vfwmsgs.h:19
#define typeof(X_)
Definition: msvc.h:2
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define ERROR_NO_SYSTEM_RESOURCES
Definition: winerror.h:1276
#define ioctl
Definition: wintirpc.h:60
unsigned char BYTE
Definition: xxhash.c:193