Commit 62e2d7a9 authored by Alexandre Julliard's avatar Alexandre Julliard

qcap: Convert the Unix library to the __wine_unix_call interface.

parent 626f85f5
MODULE = qcap.dll MODULE = qcap.dll
UNIXLIB = qcap.so
IMPORTS = strmbase strmiids uuid ole32 oleaut32 IMPORTS = strmbase strmiids uuid ole32 oleaut32
DELAYIMPORTS = msvfw32 DELAYIMPORTS = msvfw32
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#define NONAMELESSSTRUCT #define NONAMELESSSTRUCT
#define NONAMELESSUNION #define NONAMELESSUNION
#include "dshow.h" #include "dshow.h"
#include "winternl.h"
#include "wine/unixlib.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/strmbase.h" #include "wine/strmbase.h"
...@@ -38,25 +40,108 @@ HRESULT file_writer_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; ...@@ -38,25 +40,108 @@ HRESULT file_writer_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
HRESULT smart_tee_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; HRESULT smart_tee_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
HRESULT vfw_capture_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; HRESULT vfw_capture_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
struct video_capture_funcs struct video_capture_device;
{
struct video_capture_device *(CDECL *create)(USHORT index); struct create_params
void (CDECL *destroy)(struct video_capture_device *device); {
HRESULT (CDECL *check_format)(struct video_capture_device *device, const AM_MEDIA_TYPE *mt); unsigned int index;
HRESULT (CDECL *set_format)(struct video_capture_device *device, const AM_MEDIA_TYPE *mt); struct video_capture_device **device;
void (CDECL *get_format)(struct video_capture_device *device, AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format); };
HRESULT (CDECL *get_media_type)(struct video_capture_device *device,
unsigned int index, AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format); struct destroy_params
void (CDECL *get_caps)(struct video_capture_device *device, LONG index, AM_MEDIA_TYPE *mt, {
VIDEOINFOHEADER *format, VIDEO_STREAM_CONFIG_CAPS *caps); struct video_capture_device *device;
LONG (CDECL *get_caps_count)(struct video_capture_device *device); };
HRESULT (CDECL *get_prop_range)(struct video_capture_device *device, VideoProcAmpProperty property,
LONG *min, LONG *max, LONG *step, LONG *default_value, LONG *flags); struct check_format_params
HRESULT (CDECL *get_prop)(struct video_capture_device *device, {
VideoProcAmpProperty property, LONG *value, LONG *flags); struct video_capture_device *device;
HRESULT (CDECL *set_prop)(struct video_capture_device *device, const AM_MEDIA_TYPE *mt;
VideoProcAmpProperty property, LONG value, LONG flags); };
BOOL (CDECL *read_frame)(struct video_capture_device *device, BYTE *data);
struct set_format_params
{
struct video_capture_device *device;
const AM_MEDIA_TYPE *mt;
};
struct get_format_params
{
struct video_capture_device *device;
AM_MEDIA_TYPE *mt;
VIDEOINFOHEADER *format;
};
struct get_media_type_params
{
struct video_capture_device *device;
unsigned int index;
AM_MEDIA_TYPE *mt;
VIDEOINFOHEADER *format;
};
struct get_caps_params
{
struct video_capture_device *device;
unsigned int index;
AM_MEDIA_TYPE *mt;
VIDEOINFOHEADER *format;
VIDEO_STREAM_CONFIG_CAPS *caps;
};
struct get_caps_count_params
{
struct video_capture_device *device;
int *count;
};
struct get_prop_range_params
{
struct video_capture_device *device;
VideoProcAmpProperty property;
LONG *min;
LONG *max;
LONG *step;
LONG *default_value;
LONG *flags;
};
struct get_prop_params
{
struct video_capture_device *device;
VideoProcAmpProperty property;
LONG *value;
LONG *flags;
};
struct set_prop_params
{
struct video_capture_device *device;
VideoProcAmpProperty property;
LONG value;
LONG flags;
};
struct read_frame_params
{
struct video_capture_device *device;
void *data;
};
enum unix_funcs
{
unix_create,
unix_destroy,
unix_check_format,
unix_set_format,
unix_get_format,
unix_get_media_type,
unix_get_caps,
unix_get_caps_count,
unix_get_prop_range,
unix_get_prop,
unix_set_prop,
unix_read_frame,
}; };
#endif #endif
...@@ -23,7 +23,9 @@ ...@@ -23,7 +23,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(quartz); WINE_DEFAULT_DEBUG_CHANNEL(quartz);
static const struct video_capture_funcs *capture_funcs; static unixlib_handle_t v4l_handle;
#define V4L_CALL( func, params ) __wine_unix_call( v4l_handle, unix_ ## func, params )
struct vfw_capture struct vfw_capture
{ {
...@@ -95,7 +97,10 @@ static void vfw_capture_destroy(struct strmbase_filter *iface) ...@@ -95,7 +97,10 @@ static void vfw_capture_destroy(struct strmbase_filter *iface)
struct vfw_capture *filter = impl_from_strmbase_filter(iface); struct vfw_capture *filter = impl_from_strmbase_filter(iface);
if (filter->init) if (filter->init)
capture_funcs->destroy(filter->device); {
struct destroy_params params = { filter->device };
V4L_CALL( destroy, &params );
}
if (filter->source.pin.peer) if (filter->source.pin.peer)
{ {
...@@ -139,6 +144,7 @@ static DWORD WINAPI stream_thread(void *arg) ...@@ -139,6 +144,7 @@ static DWORD WINAPI stream_thread(void *arg)
{ {
struct vfw_capture *filter = arg; struct vfw_capture *filter = arg;
const unsigned int image_size = get_image_size(filter); const unsigned int image_size = get_image_size(filter);
struct read_frame_params params;
for (;;) for (;;)
{ {
...@@ -168,7 +174,9 @@ static DWORD WINAPI stream_thread(void *arg) ...@@ -168,7 +174,9 @@ static DWORD WINAPI stream_thread(void *arg)
IMediaSample_SetActualDataLength(sample, image_size); IMediaSample_SetActualDataLength(sample, image_size);
IMediaSample_GetPointer(sample, &data); IMediaSample_GetPointer(sample, &data);
if (!capture_funcs->read_frame(filter->device, data)) params.device = filter->device;
params.data = data;
if (!V4L_CALL( read_frame, &params ))
{ {
IMediaSample_Release(sample); IMediaSample_Release(sample);
break; break;
...@@ -284,6 +292,7 @@ static HRESULT WINAPI ...@@ -284,6 +292,7 @@ static HRESULT WINAPI
AMStreamConfig_SetFormat(IAMStreamConfig *iface, AM_MEDIA_TYPE *pmt) AMStreamConfig_SetFormat(IAMStreamConfig *iface, AM_MEDIA_TYPE *pmt)
{ {
struct vfw_capture *This = impl_from_IAMStreamConfig(iface); struct vfw_capture *This = impl_from_IAMStreamConfig(iface);
struct set_format_params params;
HRESULT hr; HRESULT hr;
TRACE("filter %p, mt %p.\n", This, pmt); TRACE("filter %p, mt %p.\n", This, pmt);
...@@ -312,7 +321,9 @@ AMStreamConfig_SetFormat(IAMStreamConfig *iface, AM_MEDIA_TYPE *pmt) ...@@ -312,7 +321,9 @@ AMStreamConfig_SetFormat(IAMStreamConfig *iface, AM_MEDIA_TYPE *pmt)
return VFW_E_INVALIDMEDIATYPE; return VFW_E_INVALIDMEDIATYPE;
} }
hr = capture_funcs->set_format(This->device, pmt); params.device = This->device;
params.mt = pmt;
hr = V4L_CALL( set_format, &params );
if (SUCCEEDED(hr) && This->filter.graph && This->source.pin.peer) if (SUCCEEDED(hr) && This->filter.graph && This->source.pin.peer)
{ {
hr = IFilterGraph_Reconnect(This->filter.graph, &This->source.pin.IPin_iface); hr = IFilterGraph_Reconnect(This->filter.graph, &This->source.pin.IPin_iface);
...@@ -344,7 +355,8 @@ static HRESULT WINAPI AMStreamConfig_GetFormat(IAMStreamConfig *iface, AM_MEDIA_ ...@@ -344,7 +355,8 @@ static HRESULT WINAPI AMStreamConfig_GetFormat(IAMStreamConfig *iface, AM_MEDIA_
{ {
if ((format = CoTaskMemAlloc(sizeof(VIDEOINFOHEADER)))) if ((format = CoTaskMemAlloc(sizeof(VIDEOINFOHEADER))))
{ {
capture_funcs->get_format(filter->device, *mt, format); struct get_format_params params = { filter->device, *mt, format };
V4L_CALL( get_format, &params );
(*mt)->cbFormat = sizeof(VIDEOINFOHEADER); (*mt)->cbFormat = sizeof(VIDEOINFOHEADER);
(*mt)->pbFormat = (BYTE *)format; (*mt)->pbFormat = (BYTE *)format;
hr = S_OK; hr = S_OK;
...@@ -368,13 +380,14 @@ static HRESULT WINAPI AMStreamConfig_GetNumberOfCapabilities(IAMStreamConfig *if ...@@ -368,13 +380,14 @@ static HRESULT WINAPI AMStreamConfig_GetNumberOfCapabilities(IAMStreamConfig *if
int *count, int *size) int *count, int *size)
{ {
struct vfw_capture *filter = impl_from_IAMStreamConfig(iface); struct vfw_capture *filter = impl_from_IAMStreamConfig(iface);
struct get_caps_count_params params = { filter->device, count };
TRACE("filter %p, count %p, size %p.\n", filter, count, size); TRACE("filter %p, count %p, size %p.\n", filter, count, size);
if (!count || !size) if (!count || !size)
return E_POINTER; return E_POINTER;
*count = capture_funcs->get_caps_count(filter->device); V4L_CALL( get_caps_count, &params );
*size = sizeof(VIDEO_STREAM_CONFIG_CAPS); *size = sizeof(VIDEO_STREAM_CONFIG_CAPS);
return S_OK; return S_OK;
...@@ -386,10 +399,14 @@ static HRESULT WINAPI AMStreamConfig_GetStreamCaps(IAMStreamConfig *iface, ...@@ -386,10 +399,14 @@ static HRESULT WINAPI AMStreamConfig_GetStreamCaps(IAMStreamConfig *iface,
struct vfw_capture *filter = impl_from_IAMStreamConfig(iface); struct vfw_capture *filter = impl_from_IAMStreamConfig(iface);
VIDEOINFOHEADER *format; VIDEOINFOHEADER *format;
AM_MEDIA_TYPE *mt; AM_MEDIA_TYPE *mt;
int count;
struct get_caps_count_params count_params = { filter->device, &count };
struct get_caps_params caps_params;
TRACE("filter %p, index %d, pmt %p, vscc %p.\n", filter, index, pmt, vscc); TRACE("filter %p, index %d, pmt %p, vscc %p.\n", filter, index, pmt, vscc);
if (index > capture_funcs->get_caps_count(filter->device)) V4L_CALL( get_caps_count, &count_params );
if (index > count)
return S_FALSE; return S_FALSE;
if (!(mt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)))) if (!(mt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))))
...@@ -401,7 +418,12 @@ static HRESULT WINAPI AMStreamConfig_GetStreamCaps(IAMStreamConfig *iface, ...@@ -401,7 +418,12 @@ static HRESULT WINAPI AMStreamConfig_GetStreamCaps(IAMStreamConfig *iface,
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
capture_funcs->get_caps(filter->device, index, mt, format, (VIDEO_STREAM_CONFIG_CAPS *)vscc); caps_params.device = filter->device;
caps_params.index = index;
caps_params.mt = mt;
caps_params.format = format;
caps_params.caps = (VIDEO_STREAM_CONFIG_CAPS *)vscc;
V4L_CALL( get_caps, &caps_params );
mt->cbFormat = sizeof(VIDEOINFOHEADER); mt->cbFormat = sizeof(VIDEOINFOHEADER);
mt->pbFormat = (BYTE *)format; mt->pbFormat = (BYTE *)format;
*pmt = mt; *pmt = mt;
...@@ -441,32 +463,34 @@ static HRESULT WINAPI AMVideoProcAmp_GetRange(IAMVideoProcAmp *iface, LONG prope ...@@ -441,32 +463,34 @@ static HRESULT WINAPI AMVideoProcAmp_GetRange(IAMVideoProcAmp *iface, LONG prope
LONG *min, LONG *max, LONG *step, LONG *default_value, LONG *flags) LONG *min, LONG *max, LONG *step, LONG *default_value, LONG *flags)
{ {
struct vfw_capture *filter = impl_from_IAMVideoProcAmp(iface); struct vfw_capture *filter = impl_from_IAMVideoProcAmp(iface);
struct get_prop_range_params params = { filter->device, property, min, max, step, default_value, flags };
TRACE("filter %p, property %#x, min %p, max %p, step %p, default_value %p, flags %p.\n", TRACE("filter %p, property %#x, min %p, max %p, step %p, default_value %p, flags %p.\n",
filter, property, min, max, step, default_value, flags); filter, property, min, max, step, default_value, flags);
return capture_funcs->get_prop_range(filter->device, property, min, return V4L_CALL( get_prop_range, &params );
max, step, default_value, flags);
} }
static HRESULT WINAPI AMVideoProcAmp_Set(IAMVideoProcAmp *iface, LONG property, static HRESULT WINAPI AMVideoProcAmp_Set(IAMVideoProcAmp *iface, LONG property,
LONG value, LONG flags) LONG value, LONG flags)
{ {
struct vfw_capture *filter = impl_from_IAMVideoProcAmp(iface); struct vfw_capture *filter = impl_from_IAMVideoProcAmp(iface);
struct set_prop_params params = { filter->device, property, value, flags };
TRACE("filter %p, property %#x, value %d, flags %#x.\n", filter, property, value, flags); TRACE("filter %p, property %#x, value %d, flags %#x.\n", filter, property, value, flags);
return capture_funcs->set_prop(filter->device, property, value, flags); return V4L_CALL( set_prop, &params );
} }
static HRESULT WINAPI AMVideoProcAmp_Get(IAMVideoProcAmp *iface, LONG property, static HRESULT WINAPI AMVideoProcAmp_Get(IAMVideoProcAmp *iface, LONG property,
LONG *value, LONG *flags) LONG *value, LONG *flags)
{ {
struct vfw_capture *filter = impl_from_IAMVideoProcAmp(iface); struct vfw_capture *filter = impl_from_IAMVideoProcAmp(iface);
struct get_prop_params params = { filter->device, property, value, flags };
TRACE("filter %p, property %#x, value %p, flags %p.\n", filter, property, value, flags); TRACE("filter %p, property %#x, value %p, flags %p.\n", filter, property, value, flags);
return capture_funcs->get_prop(filter->device, property, value, flags); return V4L_CALL( get_prop, &params );
} }
static const IAMVideoProcAmpVtbl IAMVideoProcAmp_VTable = static const IAMVideoProcAmpVtbl IAMVideoProcAmp_VTable =
...@@ -519,6 +543,7 @@ static HRESULT WINAPI PPB_InitNew(IPersistPropertyBag * iface) ...@@ -519,6 +543,7 @@ static HRESULT WINAPI PPB_InitNew(IPersistPropertyBag * iface)
static HRESULT WINAPI PPB_Load(IPersistPropertyBag *iface, IPropertyBag *bag, IErrorLog *error_log) static HRESULT WINAPI PPB_Load(IPersistPropertyBag *iface, IPropertyBag *bag, IErrorLog *error_log)
{ {
struct vfw_capture *filter = impl_from_IPersistPropertyBag(iface); struct vfw_capture *filter = impl_from_IPersistPropertyBag(iface);
struct create_params params;
HRESULT hr; HRESULT hr;
VARIANT var; VARIANT var;
...@@ -528,11 +553,12 @@ static HRESULT WINAPI PPB_Load(IPersistPropertyBag *iface, IPropertyBag *bag, IE ...@@ -528,11 +553,12 @@ static HRESULT WINAPI PPB_Load(IPersistPropertyBag *iface, IPropertyBag *bag, IE
if (FAILED(hr = IPropertyBag_Read(bag, L"VFWIndex", &var, error_log))) if (FAILED(hr = IPropertyBag_Read(bag, L"VFWIndex", &var, error_log)))
return hr; return hr;
if (!(filter->device = capture_funcs->create(V_I4(&var)))) params.index = V_I4(&var);
return E_FAIL; params.device = &filter->device;
hr = V4L_CALL( create, &params );
filter->init = TRUE; if (SUCCEEDED(hr)) filter->init = TRUE;
return S_OK; return hr;
} }
static HRESULT WINAPI static HRESULT WINAPI
...@@ -639,20 +665,26 @@ static inline struct vfw_capture *impl_from_strmbase_pin(struct strmbase_pin *pi ...@@ -639,20 +665,26 @@ static inline struct vfw_capture *impl_from_strmbase_pin(struct strmbase_pin *pi
static HRESULT source_query_accept(struct strmbase_pin *pin, const AM_MEDIA_TYPE *mt) static HRESULT source_query_accept(struct strmbase_pin *pin, const AM_MEDIA_TYPE *mt)
{ {
struct vfw_capture *filter = impl_from_strmbase_pin(pin); struct vfw_capture *filter = impl_from_strmbase_pin(pin);
return capture_funcs->check_format(filter->device, mt); struct check_format_params params = { filter->device, mt };
return V4L_CALL( check_format, &params );
} }
static HRESULT source_get_media_type(struct strmbase_pin *pin, static HRESULT source_get_media_type(struct strmbase_pin *pin,
unsigned int index, AM_MEDIA_TYPE *mt) unsigned int index, AM_MEDIA_TYPE *mt)
{ {
struct vfw_capture *filter = impl_from_strmbase_pin(pin); struct vfw_capture *filter = impl_from_strmbase_pin(pin);
struct get_media_type_params params;
VIDEOINFOHEADER *format; VIDEOINFOHEADER *format;
HRESULT hr; HRESULT hr;
if (!(format = CoTaskMemAlloc(sizeof(*format)))) if (!(format = CoTaskMemAlloc(sizeof(*format))))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
if ((hr = capture_funcs->get_media_type(filter->device, index, mt, format)) != S_OK) params.device = filter->device;
params.index = index;
params.mt = mt;
params.format = format;
if ((hr = V4L_CALL( get_media_type, &params )) != S_OK)
{ {
CoTaskMemFree(format); CoTaskMemFree(format);
return hr; return hr;
...@@ -826,7 +858,8 @@ static const IAMVideoControlVtbl IAMVideoControl_VTable = ...@@ -826,7 +858,8 @@ static const IAMVideoControlVtbl IAMVideoControl_VTable =
static BOOL WINAPI load_capture_funcs(INIT_ONCE *once, void *param, void **context) static BOOL WINAPI load_capture_funcs(INIT_ONCE *once, void *param, void **context)
{ {
__wine_init_unix_lib(qcap_instance, DLL_PROCESS_ATTACH, NULL, &capture_funcs); NtQueryVirtualMemory( GetCurrentProcess(), qcap_instance, MemoryWineUnixFuncs,
&v4l_handle, sizeof(v4l_handle), NULL );
return TRUE; return TRUE;
} }
...@@ -836,7 +869,7 @@ HRESULT vfw_capture_create(IUnknown *outer, IUnknown **out) ...@@ -836,7 +869,7 @@ HRESULT vfw_capture_create(IUnknown *outer, IUnknown **out)
{ {
struct vfw_capture *object; struct vfw_capture *object;
if (!InitOnceExecuteOnce(&init_once, load_capture_funcs, NULL, NULL) || !capture_funcs) if (!InitOnceExecuteOnce(&init_once, load_capture_funcs, NULL, NULL) || !v4l_handle)
return E_FAIL; return E_FAIL;
if (!(object = calloc(1, sizeof(*object)))) if (!(object = calloc(1, sizeof(*object))))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment