Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
84e55192
Commit
84e55192
authored
Dec 04, 2019
by
Zebediah Figura
Committed by
Alexandre Julliard
Dec 05, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
qcap: Rework v4l2 state change logic.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
74df86d8
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
91 additions
and
146 deletions
+91
-146
capture.h
dlls/qcap/capture.h
+4
-3
v4l.c
dlls/qcap/v4l.c
+54
-116
vfwcapture.c
dlls/qcap/vfwcapture.c
+33
-27
No files found.
dlls/qcap/capture.h
View file @
84e55192
...
...
@@ -31,8 +31,9 @@ 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
;
HRESULT
qcap_driver_get_prop
(
Capture
*
,
VideoProcAmpProperty
,
LONG
*
,
LONG
*
)
DECLSPEC_HIDDEN
;
HRESULT
qcap_driver_set_prop
(
Capture
*
,
VideoProcAmpProperty
,
LONG
,
LONG
)
DECLSPEC_HIDDEN
;
HRESULT
qcap_driver_run
(
Capture
*
,
FILTER_STATE
*
)
DECLSPEC_HIDDEN
;
HRESULT
qcap_driver_pause
(
Capture
*
,
FILTER_STATE
*
)
DECLSPEC_HIDDEN
;
HRESULT
qcap_driver_stop
(
Capture
*
,
FILTER_STATE
*
)
DECLSPEC_HIDDEN
;
void
qcap_driver_init_stream
(
Capture
*
device
)
DECLSPEC_HIDDEN
;
void
qcap_driver_start_stream
(
Capture
*
device
)
DECLSPEC_HIDDEN
;
void
qcap_driver_stop_stream
(
Capture
*
device
)
DECLSPEC_HIDDEN
;
void
qcap_driver_cleanup_stream
(
Capture
*
device
)
DECLSPEC_HIDDEN
;
#endif
/* __QCAP_CAPTURE_H__ */
dlls/qcap/v4l.c
View file @
84e55192
...
...
@@ -99,13 +99,11 @@ struct _Capture
UINT
width
,
height
,
bitDepth
,
fps
,
outputwidth
,
outputheight
;
BOOL
swresize
;
CRITICAL_SECTION
CritSect
;
struct
strmbase_source
*
pin
;
int
fd
,
mmap
;
BOOL
iscommitted
,
stopped
;
FILTER_STATE
state
;
HANDLE
thread
;
HANDLE
thread
,
run_event
;
};
static
int
xioctl
(
int
fd
,
int
request
,
void
*
arg
)
...
...
@@ -125,8 +123,6 @@ HRESULT qcap_driver_destroy(Capture *capBox)
if
(
capBox
->
fd
!=
-
1
)
video_close
(
capBox
->
fd
);
capBox
->
CritSect
.
DebugInfo
->
Spare
[
0
]
=
0
;
DeleteCriticalSection
(
&
capBox
->
CritSect
);
CoTaskMemFree
(
capBox
);
return
S_OK
;
}
...
...
@@ -397,16 +393,14 @@ static DWORD WINAPI ReadThread(LPVOID lParam)
if
(
!
(
image_data
=
heap_alloc
(
image_size
)))
{
ERR
(
"Failed to allocate memory.
\n
"
);
capBox
->
thread
=
0
;
capBox
->
stopped
=
TRUE
;
return
0
;
}
while
(
1
)
while
(
capBox
->
state
!=
State_Stopped
)
{
EnterCriticalSection
(
&
capBox
->
CritSect
);
if
(
capBox
->
stopped
)
break
;
if
(
capBox
->
state
==
State_Paused
)
WaitForSingleObject
(
capBox
->
run_event
,
INFINITE
);
hr
=
BaseOutputPinImpl_GetDeliveryBuffer
(
capBox
->
pin
,
&
pSample
,
NULL
,
NULL
,
0
);
if
(
SUCCEEDED
(
hr
))
{
...
...
@@ -440,124 +434,66 @@ static DWORD WINAPI ReadThread(LPVOID lParam)
if
(
FAILED
(
hr
)
&&
hr
!=
VFW_E_NOT_CONNECTED
)
{
TRACE
(
"Return %x, stop IFilterGraph
\n
"
,
hr
);
capBox
->
thread
=
0
;
capBox
->
stopped
=
TRUE
;
break
;
}
LeaveCriticalSection
(
&
capBox
->
CritSect
);
}
LeaveCriticalSection
(
&
capBox
->
CritSect
);
heap_free
(
image_data
);
return
0
;
}
HRESULT
qcap_driver_run
(
Capture
*
capBox
,
FILTER_STATE
*
stat
e
)
void
qcap_driver_init_stream
(
Capture
*
devic
e
)
{
HANDLE
thread
;
ALLOCATOR_PROPERTIES
req_props
,
ret_props
;
HRESULT
hr
;
TRACE
(
"%p -> (%p)
\n
"
,
capBox
,
state
);
if
(
*
state
==
State_Running
)
return
S_OK
;
EnterCriticalSection
(
&
capBox
->
CritSect
);
req_props
.
cBuffers
=
3
;
if
(
!
device
->
swresize
)
req_props
.
cbBuffer
=
device
->
width
*
device
->
height
;
else
req_props
.
cbBuffer
=
device
->
outputwidth
*
device
->
outputheight
;
req_props
.
cbBuffer
=
(
req_props
.
cbBuffer
*
device
->
bitDepth
)
/
8
;
req_props
.
cbAlign
=
1
;
req_props
.
cbPrefix
=
0
;
capBox
->
stopped
=
FALSE
;
hr
=
IMemAllocator_SetProperties
(
device
->
pin
->
pAllocator
,
&
req_props
,
&
ret_props
);
if
(
FAILED
(
hr
))
ERR
(
"Failed to set allocator properties (buffer size %u), hr %#x.
\n
"
,
req_props
.
cbBuffer
,
hr
);
if
(
*
state
==
State_Stopped
&&
capBox
->
pin
->
pin
.
peer
)
if
(
SUCCEEDED
(
hr
)
)
{
*
state
=
State_Running
;
if
(
!
capBox
->
iscommitted
)
{
ALLOCATOR_PROPERTIES
ap
,
actual
;
capBox
->
iscommitted
=
TRUE
;
ap
.
cBuffers
=
3
;
if
(
!
capBox
->
swresize
)
ap
.
cbBuffer
=
capBox
->
width
*
capBox
->
height
;
else
ap
.
cbBuffer
=
capBox
->
outputwidth
*
capBox
->
outputheight
;
ap
.
cbBuffer
=
(
ap
.
cbBuffer
*
capBox
->
bitDepth
)
/
8
;
ap
.
cbAlign
=
1
;
ap
.
cbPrefix
=
0
;
hr
=
IMemAllocator_SetProperties
(
capBox
->
pin
->
pAllocator
,
&
ap
,
&
actual
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_Commit
(
capBox
->
pin
->
pAllocator
);
TRACE
(
"Committing allocator: %x
\n
"
,
hr
);
}
thread
=
CreateThread
(
NULL
,
0
,
ReadThread
,
capBox
,
0
,
NULL
);
if
(
thread
)
{
capBox
->
thread
=
thread
;
SetThreadPriority
(
thread
,
THREAD_PRIORITY_LOWEST
);
LeaveCriticalSection
(
&
capBox
->
CritSect
);
return
S_OK
;
}
ERR
(
"Creating thread failed.. %u
\n
"
,
GetLastError
());
LeaveCriticalSection
(
&
capBox
->
CritSect
);
return
E_FAIL
;
if
(
FAILED
(
hr
=
IMemAllocator_Commit
(
device
->
pin
->
pAllocator
)))
ERR
(
"Failed to commit allocator, hr %#x.
\n
"
,
hr
);
}
ResumeThread
(
capBox
->
thread
);
*
state
=
State_Running
;
LeaveCriticalSection
(
&
capBox
->
CritSect
);
return
S_OK
;
device
->
state
=
State_Paused
;
device
->
thread
=
CreateThread
(
NULL
,
0
,
ReadThread
,
device
,
0
,
NULL
);
}
HRESULT
qcap_driver_pause
(
Capture
*
capBox
,
FILTER_STATE
*
stat
e
)
void
qcap_driver_start_stream
(
Capture
*
devic
e
)
{
TRACE
(
"%p -> (%p)
\n
"
,
capBox
,
state
);
if
(
*
state
==
State_Paused
)
return
S_OK
;
if
(
*
state
==
State_Stopped
)
qcap_driver_run
(
capBox
,
state
);
EnterCriticalSection
(
&
capBox
->
CritSect
);
*
state
=
State_Paused
;
SuspendThread
(
capBox
->
thread
);
LeaveCriticalSection
(
&
capBox
->
CritSect
);
return
S_OK
;
device
->
state
=
State_Running
;
SetEvent
(
device
->
run_event
);
}
HRESULT
qcap_driver_stop
(
Capture
*
capBox
,
FILTER_STATE
*
stat
e
)
void
qcap_driver_stop_stream
(
Capture
*
devic
e
)
{
TRACE
(
"%p -> (%p)
\n
"
,
capBox
,
state
);
if
(
*
state
==
State_Stopped
)
return
S_OK
;
EnterCriticalSection
(
&
capBox
->
CritSect
);
if
(
capBox
->
thread
)
{
if
(
*
state
==
State_Paused
)
ResumeThread
(
capBox
->
thread
);
capBox
->
stopped
=
TRUE
;
capBox
->
thread
=
0
;
if
(
capBox
->
iscommitted
)
{
HRESULT
hr
;
capBox
->
iscommitted
=
FALSE
;
device
->
state
=
State_Paused
;
ResetEvent
(
device
->
run_event
);
}
hr
=
IMemAllocator_Decommit
(
capBox
->
pin
->
pAllocator
);
void
qcap_driver_cleanup_stream
(
Capture
*
device
)
{
HRESULT
hr
;
if
(
hr
!=
S_OK
&&
hr
!=
VFW_E_NOT_COMMITTED
)
WARN
(
"Decommitting allocator: %x
\n
"
,
hr
);
}
}
device
->
state
=
State_Stopped
;
WaitForSingleObject
(
device
->
thread
,
INFINITE
);
CloseHandle
(
device
->
thread
);
device
->
thread
=
NULL
;
*
state
=
State_Stopped
;
LeaveCriticalSection
(
&
capBox
->
CritSect
);
return
S_OK
;
hr
=
IMemAllocator_Decommit
(
device
->
pin
->
pAllocator
)
;
if
(
hr
!=
S_OK
&&
hr
!=
VFW_E_NOT_COMMITTED
)
ERR
(
"Failed to decommit allocator, hr %#x.
\n
"
,
hr
)
;
}
Capture
*
qcap_driver_init
(
struct
strmbase_source
*
pin
,
USHORT
card
)
...
...
@@ -574,9 +510,6 @@ Capture *qcap_driver_init(struct strmbase_source *pin, USHORT card)
if
(
!
(
device
=
CoTaskMemAlloc
(
sizeof
(
*
device
))))
return
NULL
;
InitializeCriticalSection
(
&
device
->
CritSect
);
device
->
CritSect
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": Capture.CritSect"
);
sprintf
(
path
,
"/dev/video%i"
,
card
);
TRACE
(
"Opening device %s.
\n
"
,
path
);
#ifdef O_CLOEXEC
...
...
@@ -643,8 +576,8 @@ Capture *qcap_driver_init(struct strmbase_source *pin, USHORT card)
device
->
bitDepth
=
24
;
device
->
pin
=
pin
;
device
->
fps
=
3
;
device
->
st
opped
=
FALSE
;
device
->
iscommitted
=
FALSE
;
device
->
st
ate
=
State_Stopped
;
device
->
run_event
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
NULL
)
;
TRACE
(
"Format: %d bpp - %dx%d.
\n
"
,
device
->
bitDepth
,
device
->
width
,
device
->
height
);
...
...
@@ -709,19 +642,24 @@ HRESULT qcap_driver_set_prop(Capture *capBox, VideoProcAmpProperty Property,
FAIL_WITH_ERR
;
}
HRESULT
qcap_driver_run
(
Capture
*
capBox
,
FILTER_STATE
*
stat
e
)
void
qcap_driver_init_stream
(
Capture
*
devic
e
)
{
FAIL_WITH_ERR
;
ERR
(
"v4l absent: shouldn't be called
\n
"
)
;
}
HRESULT
qcap_driver_pause
(
Capture
*
capBox
,
FILTER_STATE
*
stat
e
)
void
qcap_driver_start_stream
(
Capture
*
devic
e
)
{
FAIL_WITH_ERR
;
ERR
(
"v4l absent: shouldn't be called
\n
"
)
;
}
HRESULT
qcap_driver_stop
(
Capture
*
capBox
,
FILTER_STATE
*
stat
e
)
void
qcap_driver_stop_stream
(
Capture
*
devic
e
)
{
FAIL_WITH_ERR
;
ERR
(
"v4l absent: shouldn't be called
\n
"
);
}
void
qcap_driver_cleanup_stream
(
Capture
*
device
)
{
ERR
(
"v4l absent: shouldn't be called
\n
"
);
}
#endif
/* defined(VIDIOCMCAPTURE) */
dlls/qcap/vfwcapture.c
View file @
84e55192
...
...
@@ -62,11 +62,6 @@ static inline VfwCapture *impl_from_strmbase_filter(struct strmbase_filter *ifac
return
CONTAINING_RECORD
(
iface
,
VfwCapture
,
filter
);
}
static
inline
VfwCapture
*
impl_from_IBaseFilter
(
IBaseFilter
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
VfwCapture
,
filter
.
IBaseFilter_iface
);
}
static
inline
VfwCapture
*
impl_from_IAMStreamConfig
(
IAMStreamConfig
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
VfwCapture
,
IAMStreamConfig_iface
);
...
...
@@ -99,7 +94,7 @@ static void vfw_capture_destroy(struct strmbase_filter *iface)
if
(
filter
->
init
)
{
if
(
filter
->
filter
.
state
!=
State_Stopped
)
qcap_driver_stop
(
filter
->
driver_info
,
&
filter
->
filter
.
state
);
qcap_driver_stop
_stream
(
filter
->
driver_info
);
qcap_driver_destroy
(
filter
->
driver_info
);
}
...
...
@@ -129,47 +124,58 @@ static HRESULT vfw_capture_query_interface(struct strmbase_filter *iface, REFIID
return
S_OK
;
}
static
const
struct
strmbase_filter_ops
filter_ops
=
static
HRESULT
vfw_capture_init_stream
(
struct
strmbase_filter
*
iface
)
{
.
filter_get_pin
=
vfw_capture_get_pin
,
.
filter_destroy
=
vfw_capture_destroy
,
.
filter_query_interface
=
vfw_capture_query_interface
,
};
VfwCapture
*
filter
=
impl_from_strmbase_filter
(
iface
);
/** IMediaFilter methods **/
qcap_driver_init_stream
(
filter
->
driver_info
);
return
VFW_S_CANT_CUE
;
}
static
HRESULT
WINAPI
VfwCapture_Stop
(
IBaseFilter
*
ifac
e
)
static
HRESULT
vfw_capture_start_stream
(
struct
strmbase_filter
*
iface
,
REFERENCE_TIME
tim
e
)
{
VfwCapture
*
This
=
impl_from_IBaseF
ilter
(
iface
);
VfwCapture
*
filter
=
impl_from_strmbase_f
ilter
(
iface
);
TRACE
(
"()
\n
"
);
return
qcap_driver_stop
(
This
->
driver_info
,
&
This
->
filter
.
state
)
;
qcap_driver_start_stream
(
filter
->
driver_info
);
return
S_OK
;
}
static
HRESULT
WINAPI
VfwCapture_Pause
(
IBaseFilter
*
iface
)
static
HRESULT
vfw_capture_stop_stream
(
struct
strmbase_filter
*
iface
)
{
VfwCapture
*
This
=
impl_from_IBaseF
ilter
(
iface
);
VfwCapture
*
filter
=
impl_from_strmbase_f
ilter
(
iface
);
TRACE
(
"()
\n
"
);
return
qcap_driver_pause
(
This
->
driver_info
,
&
This
->
filter
.
state
)
;
qcap_driver_stop_stream
(
filter
->
driver_info
);
return
VFW_S_CANT_CUE
;
}
static
HRESULT
WINAPI
VfwCapture_Run
(
IBaseFilter
*
iface
,
REFERENCE_TIME
tStart
)
static
HRESULT
vfw_capture_cleanup_stream
(
struct
strmbase_filter
*
iface
)
{
VfwCapture
*
This
=
impl_from_IBaseFilter
(
iface
);
TRACE
(
"(%s)
\n
"
,
wine_dbgstr_longlong
(
tStart
));
return
qcap_driver_run
(
This
->
driver_info
,
&
This
->
filter
.
state
);
VfwCapture
*
filter
=
impl_from_strmbase_filter
(
iface
);
qcap_driver_cleanup_stream
(
filter
->
driver_info
);
return
S_OK
;
}
static
const
struct
strmbase_filter_ops
filter_ops
=
{
.
filter_get_pin
=
vfw_capture_get_pin
,
.
filter_destroy
=
vfw_capture_destroy
,
.
filter_query_interface
=
vfw_capture_query_interface
,
.
filter_init_stream
=
vfw_capture_init_stream
,
.
filter_start_stream
=
vfw_capture_start_stream
,
.
filter_stop_stream
=
vfw_capture_stop_stream
,
.
filter_cleanup_stream
=
vfw_capture_cleanup_stream
,
};
static
const
IBaseFilterVtbl
VfwCapture_Vtbl
=
{
BaseFilterImpl_QueryInterface
,
BaseFilterImpl_AddRef
,
BaseFilterImpl_Release
,
BaseFilterImpl_GetClassID
,
VfwCapture
_Stop
,
VfwCapture
_Pause
,
VfwCapture
_Run
,
BaseFilterImpl
_Stop
,
BaseFilterImpl
_Pause
,
BaseFilterImpl
_Run
,
BaseFilterImpl_GetState
,
BaseFilterImpl_SetSyncSource
,
BaseFilterImpl_GetSyncSource
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment