From: Jeff Smith whydoubt@gmail.com
Signed-off-by: Jeff Smith whydoubt@gmail.com Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v4: Minor spacing changes; remove a not particularly necessary comment.
dlls/qcap/tests/videocapture.c | 61 ++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 11 deletions(-)
diff --git a/dlls/qcap/tests/videocapture.c b/dlls/qcap/tests/videocapture.c index 326601a398c..8bda036e1d9 100644 --- a/dlls/qcap/tests/videocapture.c +++ b/dlls/qcap/tests/videocapture.c @@ -23,6 +23,12 @@ #include "wine/test.h" #include "wine/strmbase.h"
+static BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b) +{ + return !memcmp(a, b, offsetof(AM_MEDIA_TYPE, pbFormat)) + && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat); +} + #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported) { @@ -78,11 +84,11 @@ static void test_media_types(IPin *pin) static void test_stream_config(IPin *pin) { VIDEOINFOHEADER *video_info, *video_info2; + LONG depth, compression, count, size, i; + IEnumMediaTypes *enum_media_types; AM_MEDIA_TYPE *format, *format2; - VIDEO_STREAM_CONFIG_CAPS vscc; IAMStreamConfig *stream_config; - LONG depth, compression; - LONG count, size; + VIDEO_STREAM_CONFIG_CAPS vscc; HRESULT hr;
hr = IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **)&stream_config); @@ -96,6 +102,16 @@ static void test_stream_config(IPin *pin) hr = IAMStreamConfig_SetFormat(stream_config, format); ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* After setting the format, a single media type is enumerated. + * This persists until the filter is released. */ + IPin_EnumMediaTypes(pin, &enum_media_types); + hr = IEnumMediaTypes_Next(enum_media_types, 1, &format2, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + DeleteMediaType(format2); + hr = IEnumMediaTypes_Next(enum_media_types, 1, &format2, NULL); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + IEnumMediaTypes_Release(enum_media_types); + format->majortype = MEDIATYPE_Audio; hr = IAMStreamConfig_SetFormat(stream_config, format); ok(hr == E_FAIL, "Got hr %#x.\n", hr); @@ -162,14 +178,37 @@ static void test_stream_config(IPin *pin) hr = IAMStreamConfig_GetStreamCaps(stream_config, 100000, &format, (BYTE *)&vscc); ok(hr == S_FALSE, "Got hr %#x.\n", hr);
- hr = IAMStreamConfig_GetStreamCaps(stream_config, 0, &format, (BYTE *)&vscc); - ok(hr == S_OK, "Got hr %#x.\n", hr); - ok(IsEqualGUID(&format->majortype, &MEDIATYPE_Video), "Got wrong majortype: %s.\n", - debugstr_guid(&MEDIATYPE_Video)); - ok(IsEqualGUID(&vscc.guid, &FORMAT_VideoInfo) - || IsEqualGUID(&vscc.guid, &FORMAT_VideoInfo2), "Got wrong guid: %s.\n", - debugstr_guid(&vscc.guid)); - FreeMediaType(format); + for (i = 0; i < count; ++i) + { + hr = IAMStreamConfig_GetStreamCaps(stream_config, i, &format, (BYTE *)&vscc); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(IsEqualGUID(&format->majortype, &MEDIATYPE_Video), "Got wrong majortype: %s.\n", + debugstr_guid(&MEDIATYPE_Video)); + ok(IsEqualGUID(&vscc.guid, &FORMAT_VideoInfo) + || IsEqualGUID(&vscc.guid, &FORMAT_VideoInfo2), "Got wrong guid: %s.\n", + debugstr_guid(&vscc.guid)); + + hr = IAMStreamConfig_SetFormat(stream_config, format); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IAMStreamConfig_GetFormat(stream_config, &format2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(compare_media_types(format, format2), "Media types didn't match.\n"); + DeleteMediaType(format2); + + hr = IPin_EnumMediaTypes(pin, &enum_media_types); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IEnumMediaTypes_Next(enum_media_types, 1, &format2, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + todo_wine_if (!compare_media_types(format, format2)) + ok(compare_media_types(format, format2), "Media types didn't match.\n"); + + DeleteMediaType(format2); + IEnumMediaTypes_Release(enum_media_types); + + DeleteMediaType(format); + }
IAMStreamConfig_Release(stream_config); }
From: Jeff Smith whydoubt@gmail.com
Signed-off-by: Jeff Smith whydoubt@gmail.com Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v4: No changes.
dlls/qcap/v4l.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-)
diff --git a/dlls/qcap/v4l.c b/dlls/qcap/v4l.c index d8c5e168e14..94fe6b7dd0d 100644 --- a/dlls/qcap/v4l.c +++ b/dlls/qcap/v4l.c @@ -96,6 +96,8 @@ struct v4l_device struct caps *caps; LONG caps_count;
+ int image_size, image_pitch; + struct strmbase_source *pin; int fd, mmap;
@@ -194,6 +196,8 @@ static BOOL set_caps(struct v4l_device *device, const struct caps *caps) }
device->current_caps = caps; + device->image_size = width * height * caps->video_info.bmiHeader.biBitCount / 8; + device->image_pitch = width * caps->video_info.bmiHeader.biBitCount / 8;
return TRUE; } @@ -304,15 +308,11 @@ static HRESULT v4l_device_set_prop(struct video_capture_device *iface, static void reverse_image(struct v4l_device *device, LPBYTE output, const BYTE *input) { int inoffset, outoffset, pitch; - UINT width, height, depth;
- width = device->current_caps->video_info.bmiHeader.biWidth; - height = device->current_caps->video_info.bmiHeader.biHeight; - depth = device->current_caps->video_info.bmiHeader.biBitCount / 8; /* the whole image needs to be reversed, because the dibs are messed up in windows */ - outoffset = width * height * depth; - pitch = width * depth; + outoffset = device->image_size; + pitch = device->image_pitch; inoffset = 0; while (outoffset > 0) { @@ -330,14 +330,8 @@ static DWORD WINAPI ReadThread(void *arg) HRESULT hr; IMediaSample *pSample = NULL; unsigned char *pTarget, *image_data; - unsigned int image_size; - UINT width, height, depth; - - width = device->current_caps->video_info.bmiHeader.biWidth; - height = device->current_caps->video_info.bmiHeader.biHeight; - depth = device->current_caps->video_info.bmiHeader.biBitCount / 8; - image_size = width * height * depth; - if (!(image_data = heap_alloc(image_size))) + + if (!(image_data = heap_alloc(device->image_size))) { ERR("Failed to allocate memory.\n"); return 0; @@ -363,15 +357,14 @@ static DWORD WINAPI ReadThread(void *arg) { int len;
- len = width * height * depth; - IMediaSample_SetActualDataLength(pSample, len); + IMediaSample_SetActualDataLength(pSample, device->image_size);
len = IMediaSample_GetActualDataLength(pSample); TRACE("Data length: %d KB\n", len / 1024);
IMediaSample_GetPointer(pSample, &pTarget);
- while (video_read(device->fd, image_data, image_size) == -1) + while (video_read(device->fd, image_data, device->image_size) == -1) { if (errno != EAGAIN) { @@ -403,8 +396,7 @@ static void v4l_device_init_stream(struct video_capture_device *iface) HRESULT hr;
req_props.cBuffers = 3; - req_props.cbBuffer = device->current_caps->video_info.bmiHeader.biWidth * device->current_caps->video_info.bmiHeader.biHeight; - req_props.cbBuffer = (req_props.cbBuffer * device->current_caps->video_info.bmiHeader.biBitCount) / 8; + req_props.cbBuffer = device->image_size; req_props.cbAlign = 1; req_props.cbPrefix = 0;
From: Jeff Smith whydoubt@gmail.com
Signed-off-by: Jeff Smith whydoubt@gmail.com Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v4: Minor spacing changes; change a couple types to unsigned.
dlls/qcap/qcap_private.h | 1 + dlls/qcap/tests/videocapture.c | 7 ++----- dlls/qcap/v4l.c | 16 ++++++++++++++++ dlls/qcap/vfwcapture.c | 15 ++------------- 4 files changed, 21 insertions(+), 18 deletions(-)
diff --git a/dlls/qcap/qcap_private.h b/dlls/qcap/qcap_private.h index 70a8c85ad47..bbbe2ef43ec 100644 --- a/dlls/qcap/qcap_private.h +++ b/dlls/qcap/qcap_private.h @@ -51,6 +51,7 @@ struct video_capture_device_ops HRESULT (*check_format)(struct video_capture_device *device, const AM_MEDIA_TYPE *mt); HRESULT (*set_format)(struct video_capture_device *device, const AM_MEDIA_TYPE *mt); HRESULT (*get_format)(struct video_capture_device *device, AM_MEDIA_TYPE *mt); + HRESULT (*get_media_type)(struct video_capture_device *device, unsigned int index, AM_MEDIA_TYPE *mt); HRESULT (*get_caps)(struct video_capture_device *device, LONG index, AM_MEDIA_TYPE **mt, VIDEO_STREAM_CONFIG_CAPS *caps); LONG (*get_caps_count)(struct video_capture_device *device); HRESULT (*get_prop_range)(struct video_capture_device *device, VideoProcAmpProperty property, diff --git a/dlls/qcap/tests/videocapture.c b/dlls/qcap/tests/videocapture.c index 8bda036e1d9..e8175f5df9a 100644 --- a/dlls/qcap/tests/videocapture.c +++ b/dlls/qcap/tests/videocapture.c @@ -109,7 +109,7 @@ static void test_stream_config(IPin *pin) ok(hr == S_OK, "Got hr %#x.\n", hr); DeleteMediaType(format2); hr = IEnumMediaTypes_Next(enum_media_types, 1, &format2, NULL); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); IEnumMediaTypes_Release(enum_media_types);
format->majortype = MEDIATYPE_Audio; @@ -200,10 +200,7 @@ static void test_stream_config(IPin *pin) ok(hr == S_OK, "Got hr %#x.\n", hr); hr = IEnumMediaTypes_Next(enum_media_types, 1, &format2, NULL); ok(hr == S_OK, "Got hr %#x.\n", hr); - - todo_wine_if (!compare_media_types(format, format2)) - ok(compare_media_types(format, format2), "Media types didn't match.\n"); - + ok(compare_media_types(format, format2), "Media types didn't match.\n"); DeleteMediaType(format2); IEnumMediaTypes_Release(enum_media_types);
diff --git a/dlls/qcap/v4l.c b/dlls/qcap/v4l.c index 94fe6b7dd0d..b1d7e68d426 100644 --- a/dlls/qcap/v4l.c +++ b/dlls/qcap/v4l.c @@ -227,6 +227,21 @@ static HRESULT v4l_device_get_format(struct video_capture_device *iface, AM_MEDI return CopyMediaType(mt, &device->current_caps->media_type); }
+static HRESULT v4l_device_get_media_type(struct video_capture_device *iface, + unsigned int index, AM_MEDIA_TYPE *mt) +{ + struct v4l_device *device = v4l_device(iface); + unsigned int caps_count = (device->current_caps) ? 1 : device->caps_count; + + if (index >= caps_count) + return VFW_S_NO_MORE_ITEMS; + + if (device->current_caps) + return CopyMediaType(mt, &device->current_caps->media_type); + + return CopyMediaType(mt, &device->caps[index].media_type); +} + static __u32 v4l2_cid_from_qcap_property(VideoProcAmpProperty property) { switch (property) @@ -515,6 +530,7 @@ static const struct video_capture_device_ops v4l_device_ops = .check_format = v4l_device_check_format, .set_format = v4l_device_set_format, .get_format = v4l_device_get_format, + .get_media_type = v4l_device_get_media_type, .get_caps = v4l_device_get_caps, .get_caps_count = v4l_device_get_caps_count, .get_prop_range = v4l_device_get_prop_range, diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c index 910be107b0b..c4df4cb1c81 100644 --- a/dlls/qcap/vfwcapture.c +++ b/dlls/qcap/vfwcapture.c @@ -521,21 +521,10 @@ static HRESULT source_query_accept(struct strmbase_pin *pin, const AM_MEDIA_TYPE }
static HRESULT source_get_media_type(struct strmbase_pin *pin, - unsigned int index, AM_MEDIA_TYPE *pmt) + unsigned int index, AM_MEDIA_TYPE *mt) { VfwCapture *filter = impl_from_strmbase_pin(pin); - AM_MEDIA_TYPE *vfw_pmt; - HRESULT hr; - - if (index >= filter->device->ops->get_caps_count(filter->device)) - return VFW_S_NO_MORE_ITEMS; - - if (SUCCEEDED(hr = filter->device->ops->get_caps(filter->device, index, &vfw_pmt, NULL))) - { - CopyMediaType(pmt, vfw_pmt); - DeleteMediaType(vfw_pmt); - } - return hr; + return filter->device->ops->get_media_type(filter->device, index, mt); }
static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)