Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/tests/videocapture.c | 207 +++++++++++++++++++++++++++++++-- 1 file changed, 198 insertions(+), 9 deletions(-)
diff --git a/dlls/qcap/tests/videocapture.c b/dlls/qcap/tests/videocapture.c index e8175f5df9a..fafd18009f4 100644 --- a/dlls/qcap/tests/videocapture.c +++ b/dlls/qcap/tests/videocapture.c @@ -296,6 +296,191 @@ static void test_misc_flags(IBaseFilter *filter) IAMFilterMiscFlags_Release(misc_flags); }
+struct testfilter +{ + struct strmbase_filter filter; + struct strmbase_sink sink; +}; + +static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface) +{ + return CONTAINING_RECORD(iface, struct testfilter, filter); +} + +static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index) +{ + struct testfilter *filter = impl_from_strmbase_filter(iface); + if (!index) + return &filter->sink.pin; + return NULL; +} + +static void testfilter_destroy(struct strmbase_filter *iface) +{ + struct testfilter *filter = impl_from_strmbase_filter(iface); + strmbase_sink_cleanup(&filter->sink); + strmbase_filter_cleanup(&filter->filter); +} + +static const struct strmbase_filter_ops testfilter_ops = +{ + .filter_get_pin = testfilter_get_pin, + .filter_destroy = testfilter_destroy, +}; + +static HRESULT testsink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out) +{ + struct testfilter *filter = impl_from_strmbase_filter(iface->filter); + + if (IsEqualGUID(iid, &IID_IMemInputPin)) + *out = &filter->sink.IMemInputPin_iface; + else + return E_NOINTERFACE; + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample *sample) +{ + return S_OK; +} + +static const struct strmbase_sink_ops testsink_ops = +{ + .base.pin_query_interface = testsink_query_interface, + .pfnReceive = testsink_Receive, +}; + +static void testfilter_init(struct testfilter *filter) +{ + static const GUID clsid = {0xabacab}; + memset(filter, 0, sizeof(*filter)); + strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); + strmbase_sink_init(&filter->sink, &filter->filter, L"sink", &testsink_ops, NULL); +} + +static void test_connect_pin(IBaseFilter *filter, IPin *source) +{ + AM_MEDIA_TYPE req_mt, default_mt, mt, *mts[2]; + IAMStreamConfig *stream_config; + struct testfilter testsink; + IEnumMediaTypes *enummt; + IFilterGraph2 *graph; + ULONG count, ref; + HRESULT hr; + IPin *peer; + + CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterGraph2, (void **)&graph); + testfilter_init(&testsink); + IFilterGraph2_AddFilter(graph, &testsink.filter.IBaseFilter_iface, L"sink"); + IFilterGraph2_AddFilter(graph, filter, L"source"); + hr = IPin_QueryInterface(source, &IID_IAMStreamConfig, (void **)&stream_config); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + peer = (IPin *)0xdeadbeef; + hr = IPin_ConnectedTo(source, &peer); + ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + ok(!peer, "Got peer %p.\n", peer); + + hr = IPin_ConnectionMediaType(source, &mt); + ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + + hr = IPin_EnumMediaTypes(source, &enummt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IEnumMediaTypes_Next(enummt, 2, mts, &count); + ok(SUCCEEDED(hr), "Got hr %#x.\n", hr); + CopyMediaType(&req_mt, mts[count - 1]); + CopyMediaType(&default_mt, mts[0]); + DeleteMediaType(mts[0]); + if (count > 1) + DeleteMediaType(mts[1]); + IEnumMediaTypes_Release(enummt); + + hr = IAMStreamConfig_GetFormat(stream_config, &mts[0]); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(compare_media_types(mts[0], &default_mt), "Media types didn't match.\n"); + DeleteMediaType(mts[0]); + + hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_ConnectedTo(source, &peer); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(peer == &testsink.sink.pin.IPin_iface, "Got peer %p.\n", peer); + IPin_Release(peer); + + hr = IPin_ConnectionMediaType(source, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(compare_media_types(&mt, &req_mt), "Media types didn't match.\n"); + ok(compare_media_types(&testsink.sink.pin.mt, &req_mt), "Media types didn't match.\n"); + FreeMediaType(&mt); + + hr = IAMStreamConfig_GetFormat(stream_config, &mts[0]); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(compare_media_types(mts[0], &req_mt), "Media types didn't match.\n"); + DeleteMediaType(mts[0]); + + hr = IPin_EnumMediaTypes(source, &enummt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IEnumMediaTypes_Next(enummt, 1, mts, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(compare_media_types(mts[0], &default_mt), "Media types didn't match.\n"); + DeleteMediaType(mts[0]); + IEnumMediaTypes_Release(enummt); + + hr = IFilterGraph2_Disconnect(graph, source); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph2_Disconnect(graph, source); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(testsink.sink.pin.peer == source, "Got peer %p.\n", testsink.sink.pin.peer); + IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface); + + hr = IAMStreamConfig_GetFormat(stream_config, &mts[0]); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(compare_media_types(mts[0], &default_mt), "Media types didn't match.\n"); + DeleteMediaType(mts[0]); + + FreeMediaType(&req_mt); + FreeMediaType(&default_mt); + IAMStreamConfig_Release(stream_config); + ref = IFilterGraph2_Release(graph); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IBaseFilter_Release(&testsink.filter.IBaseFilter_iface); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + +static void test_connection(IMoniker *moniker) +{ + IEnumPins *enum_pins; + IBaseFilter *filter; + HRESULT hr; + ULONG ref; + IPin *pin; + + hr = IMoniker_BindToObject(moniker, NULL, NULL, &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IBaseFilter_EnumPins(filter, &enum_pins); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + while (IEnumPins_Next(enum_pins, 1, &pin, NULL) == S_OK) + { + PIN_DIRECTION dir; + IPin_QueryDirection(pin, &dir); + if (dir == PINDIR_OUTPUT) + { + test_connect_pin(filter, pin); + } + IPin_Release(pin); + } + + IEnumPins_Release(enum_pins); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + START_TEST(videocapture) { ICreateDevEnum *dev_enum; @@ -329,17 +514,21 @@ START_TEST(videocapture) trace("Testing device %s.\n", wine_dbgstr_w(name)); CoTaskMemFree(name);
- hr = IMoniker_BindToObject(moniker, NULL, NULL, &IID_IBaseFilter, (void**)&filter); - if (hr == S_OK) + if (FAILED(hr = IMoniker_BindToObject(moniker, NULL, NULL, &IID_IBaseFilter, (void **)&filter))) { - test_filter_interfaces(filter); - test_pins(filter); - test_misc_flags(filter); - ref = IBaseFilter_Release(filter); - ok(!ref, "Got outstanding refcount %d.\n", ref); + skip("Failed to open device %s, hr %#x.\n", debugstr_w(name), hr); + IMoniker_Release(moniker); + continue; } - else - skip("Failed to open capture device, hr=%#x.\n", hr); + + test_filter_interfaces(filter); + test_pins(filter); + test_misc_flags(filter); + + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + test_connection(moniker);
IMoniker_Release(moniker); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/vfwcapture.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c index f0a985d5f4b..5c1ce9af980 100644 --- a/dlls/qcap/vfwcapture.c +++ b/dlls/qcap/vfwcapture.c @@ -344,8 +344,14 @@ static HRESULT WINAPI AMStreamConfig_GetFormat(IAMStreamConfig *iface, AM_MEDIA_ if (!(*mt = CoTaskMemAlloc(sizeof(**mt)))) return E_OUTOFMEMORY;
- if (SUCCEEDED(hr = capture_funcs->get_format(filter->device, *mt))) + EnterCriticalSection(&filter->filter.csFilter); + + if (filter->source.pin.peer) + hr = CopyMediaType(*mt, &filter->source.pin.mt); + else if (SUCCEEDED(hr = capture_funcs->get_format(filter->device, *mt))) strmbase_dump_media_type(*mt); + + LeaveCriticalSection(&filter->filter.csFilter); return hr; }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/qcap_private.h | 3 ++- dlls/qcap/v4l.c | 11 ++++------- dlls/qcap/vfwcapture.c | 26 +++++++++++++++++++++++++- 3 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/dlls/qcap/qcap_private.h b/dlls/qcap/qcap_private.h index 1d2b49d7394..834994d8cac 100644 --- a/dlls/qcap/qcap_private.h +++ b/dlls/qcap/qcap_private.h @@ -48,7 +48,8 @@ struct video_capture_funcs 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); + HRESULT (*get_caps)(struct video_capture_device *device, LONG index, AM_MEDIA_TYPE *mt, + VIDEOINFOHEADER *format, 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, LONG *min, LONG *max, LONG *step, LONG *default_value, LONG *flags); diff --git a/dlls/qcap/v4l.c b/dlls/qcap/v4l.c index d525989172a..db838f1efe4 100644 --- a/dlls/qcap/v4l.c +++ b/dlls/qcap/v4l.c @@ -374,17 +374,14 @@ static void fill_caps(__u32 pixelformat, __u32 width, __u32 height, }
static HRESULT v4l_device_get_caps(struct video_capture_device *device, LONG index, - AM_MEDIA_TYPE **type, VIDEO_STREAM_CONFIG_CAPS *vscc) + AM_MEDIA_TYPE *type, VIDEOINFOHEADER *format, VIDEO_STREAM_CONFIG_CAPS *vscc) { if (index >= device->caps_count) return S_FALSE;
- *type = CreateMediaType(&device->caps[index].media_type); - if (!*type) - return E_OUTOFMEMORY; - - if (vscc) - memcpy(vscc, &device->caps[index].config, sizeof(VIDEO_STREAM_CONFIG_CAPS)); + *vscc = device->caps[index].config; + *type = device->caps[index].media_type; + *format = device->caps[index].video_info; return S_OK; }
diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c index 5c1ce9af980..62d692226c5 100644 --- a/dlls/qcap/vfwcapture.c +++ b/dlls/qcap/vfwcapture.c @@ -375,10 +375,34 @@ static HRESULT WINAPI AMStreamConfig_GetStreamCaps(IAMStreamConfig *iface, int index, AM_MEDIA_TYPE **pmt, BYTE *vscc) { struct vfw_capture *filter = impl_from_IAMStreamConfig(iface); + VIDEOINFOHEADER *format; + AM_MEDIA_TYPE *mt; + HRESULT hr;
TRACE("filter %p, index %d, pmt %p, vscc %p.\n", filter, index, pmt, vscc);
- return capture_funcs->get_caps(filter->device, index, pmt, (VIDEO_STREAM_CONFIG_CAPS *)vscc); + if (!(mt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)))) + return E_OUTOFMEMORY; + + if (!(format = CoTaskMemAlloc(sizeof(VIDEOINFOHEADER)))) + { + CoTaskMemFree(mt); + return E_OUTOFMEMORY; + } + + if ((hr = capture_funcs->get_caps(filter->device, index, mt, + format, (VIDEO_STREAM_CONFIG_CAPS *)vscc)) == S_OK) + { + mt->cbFormat = sizeof(VIDEOINFOHEADER); + mt->pbFormat = (BYTE *)format; + *pmt = mt; + } + else + { + CoTaskMemFree(format); + CoTaskMemFree(mt); + } + return hr; }
static const IAMStreamConfigVtbl IAMStreamConfig_VTable =
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/qcap_private.h | 2 +- dlls/qcap/v4l.c | 6 +----- dlls/qcap/vfwcapture.c | 22 ++++++++-------------- 3 files changed, 10 insertions(+), 20 deletions(-)
diff --git a/dlls/qcap/qcap_private.h b/dlls/qcap/qcap_private.h index 834994d8cac..e2f032d2079 100644 --- a/dlls/qcap/qcap_private.h +++ b/dlls/qcap/qcap_private.h @@ -48,7 +48,7 @@ struct video_capture_funcs 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, + void (*get_caps)(struct video_capture_device *device, LONG index, AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format, 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/v4l.c b/dlls/qcap/v4l.c index db838f1efe4..e0a6593a024 100644 --- a/dlls/qcap/v4l.c +++ b/dlls/qcap/v4l.c @@ -373,16 +373,12 @@ static void fill_caps(__u32 pixelformat, __u32 width, __u32 height, caps->pixelformat = pixelformat; }
-static HRESULT v4l_device_get_caps(struct video_capture_device *device, LONG index, +static void v4l_device_get_caps(struct video_capture_device *device, LONG index, AM_MEDIA_TYPE *type, VIDEOINFOHEADER *format, VIDEO_STREAM_CONFIG_CAPS *vscc) { - if (index >= device->caps_count) - return S_FALSE; - *vscc = device->caps[index].config; *type = device->caps[index].media_type; *format = device->caps[index].video_info; - return S_OK; }
static LONG v4l_device_get_caps_count(struct video_capture_device *device) diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c index 62d692226c5..09cb7e36cc2 100644 --- a/dlls/qcap/vfwcapture.c +++ b/dlls/qcap/vfwcapture.c @@ -377,10 +377,12 @@ static HRESULT WINAPI AMStreamConfig_GetStreamCaps(IAMStreamConfig *iface, struct vfw_capture *filter = impl_from_IAMStreamConfig(iface); VIDEOINFOHEADER *format; AM_MEDIA_TYPE *mt; - HRESULT hr;
TRACE("filter %p, index %d, pmt %p, vscc %p.\n", filter, index, pmt, vscc);
+ if (index > capture_funcs->get_caps_count(filter->device)) + return S_FALSE; + if (!(mt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)))) return E_OUTOFMEMORY;
@@ -390,19 +392,11 @@ static HRESULT WINAPI AMStreamConfig_GetStreamCaps(IAMStreamConfig *iface, return E_OUTOFMEMORY; }
- if ((hr = capture_funcs->get_caps(filter->device, index, mt, - format, (VIDEO_STREAM_CONFIG_CAPS *)vscc)) == S_OK) - { - mt->cbFormat = sizeof(VIDEOINFOHEADER); - mt->pbFormat = (BYTE *)format; - *pmt = mt; - } - else - { - CoTaskMemFree(format); - CoTaskMemFree(mt); - } - return hr; + capture_funcs->get_caps(filter->device, index, mt, format, (VIDEO_STREAM_CONFIG_CAPS *)vscc); + mt->cbFormat = sizeof(VIDEOINFOHEADER); + mt->pbFormat = (BYTE *)format; + *pmt = mt; + return S_OK; }
static const IAMStreamConfigVtbl IAMStreamConfig_VTable =
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/qcap_private.h | 2 +- dlls/qcap/v4l.c | 5 +++-- dlls/qcap/vfwcapture.c | 24 ++++++++++++++++++++++-- 3 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/dlls/qcap/qcap_private.h b/dlls/qcap/qcap_private.h index e2f032d2079..50bc2525f0e 100644 --- a/dlls/qcap/qcap_private.h +++ b/dlls/qcap/qcap_private.h @@ -46,7 +46,7 @@ struct video_capture_funcs void (*destroy)(struct video_capture_device *device); 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); + void (*get_format)(struct video_capture_device *device, AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format); HRESULT (*get_media_type)(struct video_capture_device *device, unsigned int index, AM_MEDIA_TYPE *mt); void (*get_caps)(struct video_capture_device *device, LONG index, AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format, VIDEO_STREAM_CONFIG_CAPS *caps); diff --git a/dlls/qcap/v4l.c b/dlls/qcap/v4l.c index e0a6593a024..dd002f7b3ea 100644 --- a/dlls/qcap/v4l.c +++ b/dlls/qcap/v4l.c @@ -209,9 +209,10 @@ static HRESULT v4l_device_set_format(struct video_capture_device *device, const return set_caps(device, caps); }
-static HRESULT v4l_device_get_format(struct video_capture_device *device, AM_MEDIA_TYPE *mt) +static void v4l_device_get_format(struct video_capture_device *device, AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format) { - return CopyMediaType(mt, &device->current_caps->media_type); + *mt = device->current_caps->media_type; + *format = device->current_caps->video_info; }
static HRESULT v4l_device_get_media_type(struct video_capture_device *device, diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c index 09cb7e36cc2..e98e97b7816 100644 --- a/dlls/qcap/vfwcapture.c +++ b/dlls/qcap/vfwcapture.c @@ -337,6 +337,7 @@ AMStreamConfig_SetFormat(IAMStreamConfig *iface, AM_MEDIA_TYPE *pmt) static HRESULT WINAPI AMStreamConfig_GetFormat(IAMStreamConfig *iface, AM_MEDIA_TYPE **mt) { struct vfw_capture *filter = impl_from_IAMStreamConfig(iface); + VIDEOINFOHEADER *format; HRESULT hr;
TRACE("filter %p, mt %p.\n", filter, mt); @@ -347,11 +348,30 @@ static HRESULT WINAPI AMStreamConfig_GetFormat(IAMStreamConfig *iface, AM_MEDIA_ EnterCriticalSection(&filter->filter.csFilter);
if (filter->source.pin.peer) + { hr = CopyMediaType(*mt, &filter->source.pin.mt); - else if (SUCCEEDED(hr = capture_funcs->get_format(filter->device, *mt))) - strmbase_dump_media_type(*mt); + } + else + { + if ((format = CoTaskMemAlloc(sizeof(VIDEOINFOHEADER)))) + { + capture_funcs->get_format(filter->device, *mt, format); + (*mt)->cbFormat = sizeof(VIDEOINFOHEADER); + (*mt)->pbFormat = (BYTE *)format; + hr = S_OK; + } + else + { + hr = E_OUTOFMEMORY; + } + }
LeaveCriticalSection(&filter->filter.csFilter); + + if (SUCCEEDED(hr)) + strmbase_dump_media_type(*mt); + else + CoTaskMemFree(*mt); return hr; }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/qcap_private.h | 3 ++- dlls/qcap/v4l.c | 15 +++++++++++---- dlls/qcap/vfwcapture.c | 15 ++++++++++++++- 3 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/dlls/qcap/qcap_private.h b/dlls/qcap/qcap_private.h index 50bc2525f0e..379d9908637 100644 --- a/dlls/qcap/qcap_private.h +++ b/dlls/qcap/qcap_private.h @@ -47,7 +47,8 @@ struct video_capture_funcs 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); void (*get_format)(struct video_capture_device *device, AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format); - HRESULT (*get_media_type)(struct video_capture_device *device, unsigned int index, AM_MEDIA_TYPE *mt); + HRESULT (*get_media_type)(struct video_capture_device *device, + unsigned int index, AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format); void (*get_caps)(struct video_capture_device *device, LONG index, AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format, VIDEO_STREAM_CONFIG_CAPS *caps); LONG (*get_caps_count)(struct video_capture_device *device); diff --git a/dlls/qcap/v4l.c b/dlls/qcap/v4l.c index dd002f7b3ea..b5a599eb0bc 100644 --- a/dlls/qcap/v4l.c +++ b/dlls/qcap/v4l.c @@ -216,7 +216,7 @@ static void v4l_device_get_format(struct video_capture_device *device, AM_MEDIA_ }
static HRESULT v4l_device_get_media_type(struct video_capture_device *device, - unsigned int index, AM_MEDIA_TYPE *mt) + unsigned int index, AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format) { unsigned int caps_count = (device->current_caps) ? 1 : device->caps_count;
@@ -224,9 +224,16 @@ static HRESULT v4l_device_get_media_type(struct video_capture_device *device, 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); + { + *mt = device->current_caps->media_type; + *format = device->current_caps->video_info; + } + else + { + *mt = device->caps[index].media_type; + *format = device->caps[index].video_info; + } + return S_OK; }
static __u32 v4l2_cid_from_qcap_property(VideoProcAmpProperty property) diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c index e98e97b7816..8123dc4f6f7 100644 --- a/dlls/qcap/vfwcapture.c +++ b/dlls/qcap/vfwcapture.c @@ -658,7 +658,20 @@ static HRESULT source_get_media_type(struct strmbase_pin *pin, unsigned int index, AM_MEDIA_TYPE *mt) { struct vfw_capture *filter = impl_from_strmbase_pin(pin); - return capture_funcs->get_media_type(filter->device, index, mt); + VIDEOINFOHEADER *format; + HRESULT hr; + + if (!(format = CoTaskMemAlloc(sizeof(*format)))) + return E_OUTOFMEMORY; + + if ((hr = capture_funcs->get_media_type(filter->device, index, mt, format)) != S_OK) + { + CoTaskMemFree(format); + return hr; + } + mt->cbFormat = sizeof(VIDEOINFOHEADER); + mt->pbFormat = (BYTE *)format; + return S_OK; }
static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)