[PATCH 2/6] qcap/videocapture: Use formats from capabilities instead of hard coding.
Zebediah Figura
zfigura at codeweavers.com
Thu Apr 23 16:48:12 CDT 2020
On 4/23/20 12:28 AM, Jactry Zeng wrote:
> Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
> ---
> dlls/qcap/capture.h | 2 +-
> dlls/qcap/tests/videocapture.c | 42 ++++++++
> dlls/qcap/v4l.c | 175 +++++++++++++--------------------
> dlls/qcap/vfwcapture.c | 2 +-
> 4 files changed, 113 insertions(+), 108 deletions(-)
>
> diff --git a/dlls/qcap/capture.h b/dlls/qcap/capture.h
> index fa48324dd6..d3cf193e7f 100644
> --- a/dlls/qcap/capture.h
> +++ b/dlls/qcap/capture.h
> @@ -25,7 +25,7 @@ typedef struct _Capture Capture;
>
> Capture *qcap_driver_init(struct strmbase_source *,USHORT) DECLSPEC_HIDDEN;
> HRESULT qcap_driver_destroy(Capture*) DECLSPEC_HIDDEN;
> -HRESULT qcap_driver_check_format(Capture*,const AM_MEDIA_TYPE*) DECLSPEC_HIDDEN;
> +HRESULT qcap_driver_check_format(Capture* device,const AM_MEDIA_TYPE *mt,LONG *index) DECLSPEC_HIDDEN;
> HRESULT qcap_driver_set_format(Capture*,AM_MEDIA_TYPE*) DECLSPEC_HIDDEN;
> HRESULT qcap_driver_get_format(const Capture*,AM_MEDIA_TYPE**) DECLSPEC_HIDDEN;
> HRESULT qcap_driver_get_prop_range(Capture*,VideoProcAmpProperty,LONG*,LONG*,LONG*,LONG*,LONG*) DECLSPEC_HIDDEN;
> diff --git a/dlls/qcap/tests/videocapture.c b/dlls/qcap/tests/videocapture.c
> index 5532654650..a43875101c 100644
> --- a/dlls/qcap/tests/videocapture.c
> +++ b/dlls/qcap/tests/videocapture.c
> @@ -21,6 +21,7 @@
> #define COBJMACROS
> #include "dshow.h"
> #include "wine/test.h"
> +#include "wine/strmbase.h"
>
> static void test_media_types(IPin *pin)
> {
> @@ -59,6 +60,44 @@ static void test_media_types(IPin *pin)
> ok(hr != S_OK, "Got hr %#x.\n", hr);
> }
>
> +static void test_stream_config(IPin *pin)
> +{
> + IAMStreamConfig *stream_config;
> + VIDEOINFOHEADER *video_info;
> + AM_MEDIA_TYPE *format;
> + HRESULT hr;
> +
> + hr = IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **)&stream_config);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + hr = IAMStreamConfig_GetFormat(stream_config, &format);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> + ok(IsEqualGUID(&format->majortype, &MEDIATYPE_Video), "Got wrong majortype: %s.\n",
> + debugstr_guid(&format->majortype));
> +
> + hr = IAMStreamConfig_SetFormat(stream_config, format);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + format->majortype = MEDIATYPE_Audio;
> + hr = IAMStreamConfig_SetFormat(stream_config, format);
> + ok(hr == E_FAIL, "Got hr %#x.\n", hr);
> +
> + format->majortype = MEDIATYPE_Video;
> + video_info = (VIDEOINFOHEADER *)format->pbFormat;
> + video_info->bmiHeader.biWidth--;
> + video_info->bmiHeader.biHeight--;
> + hr = IAMStreamConfig_SetFormat(stream_config, format);
> + ok(hr == E_FAIL, "Got hr %#x.\n", hr);
> +
> + video_info->bmiHeader.biWidth = 10000000;
> + video_info->bmiHeader.biHeight = 10000000;
> + hr = IAMStreamConfig_SetFormat(stream_config, format);
> + ok(hr == E_FAIL, "Got hr %#x.\n", hr);
> + FreeMediaType(format);
> +
> + IAMStreamConfig_Release(stream_config);
> +}
> +
> static void test_capture(IBaseFilter *filter)
> {
> IEnumPins *enum_pins;
> @@ -73,7 +112,10 @@ static void test_capture(IBaseFilter *filter)
> PIN_DIRECTION pin_direction;
> IPin_QueryDirection(pin, &pin_direction);
> if (pin_direction == PINDIR_OUTPUT)
> + {
> test_media_types(pin);
> + test_stream_config(pin);
> + }
> IPin_Release(pin);
> }
>
> diff --git a/dlls/qcap/v4l.c b/dlls/qcap/v4l.c
> index 26eccf6ee3..db9117d593 100644
> --- a/dlls/qcap/v4l.c
> +++ b/dlls/qcap/v4l.c
> @@ -103,7 +103,7 @@ struct capabilitie
>
> struct _Capture
> {
> - UINT width, height, bitDepth, fps, outputwidth, outputheight;
> + UINT outputwidth, outputheight;
> struct capabilitie *current_cap;
> struct capabilitie **caps;
> LONG caps_count;
> @@ -146,126 +146,78 @@ HRESULT qcap_driver_destroy(Capture *capBox)
> return S_OK;
> }
>
> -HRESULT qcap_driver_check_format(Capture *device, const AM_MEDIA_TYPE *mt)
> +HRESULT qcap_driver_check_format(Capture *device, const AM_MEDIA_TYPE *mt, LONG *index)
I'd mildly prefer to leave this function signature like it is, and
instead introduce a helper, something like "const struct capabilitie
*find_caps(Capture *device, const AM_MEDIA_TYPE *mt)".
Somewhat separately, I also think we could shrink the "qcap_driver" API
surface to qcap_driver_get_caps(), and put find_caps() and the entire
pin_query_accept()/pin_get_media_type() implementation on the
"vfwcapture.c" side.
> {
> - HRESULT hr;
> + LONG i;
> +
> TRACE("device %p, mt %p.\n", device, mt);
>
> if (!mt)
> return E_POINTER;
>
> if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Video))
> - return S_FALSE;
> + return E_FAIL;
>
> - if (IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo) && mt->pbFormat
> - && mt->cbFormat >= sizeof(VIDEOINFOHEADER))
> + for (i = device->caps_count - 1; i >= 0; i--)
Is there a motivation for iterating through the array in reverse order here?
> {
> - VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)mt->pbFormat;
> - if (vih->bmiHeader.biBitCount == 24 && vih->bmiHeader.biCompression == BI_RGB)
> - hr = S_OK;
> - else
> + VIDEOINFOHEADER *video_info = (VIDEOINFOHEADER *)mt->pbFormat;
> + struct capabilitie *cap = device->caps[i];
> +
> + if (IsEqualIID(&mt->formattype, &cap->media_type.formattype)
> + && mt->cbFormat >= sizeof(VIDEOINFOHEADER)
> + && video_info
> + && video_info->bmiHeader.biWidth == cap->width
> + && video_info->bmiHeader.biHeight == cap->height)
> {
> - FIXME("Unsupported compression %#x, bpp %u.\n", vih->bmiHeader.biCompression,
> - vih->bmiHeader.biBitCount);
> - hr = S_FALSE;
> + if (index)
> + *index = i;
> + TRACE("matched with: %d.\n", i);
> + return S_OK;
> }
> }
> - else
> - hr = VFW_E_INVALIDMEDIATYPE;
>
> - return hr;
> + return E_FAIL;
> }
>
More information about the wine-devel
mailing list