Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
e0fe0ef0
Commit
e0fe0ef0
authored
Apr 22, 2008
by
Maarten Lankhorst
Committed by
Alexandre Julliard
Apr 23, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
quartz: Make the file source support multiple samples by preallocating enough handles.
parent
3a39805e
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
119 additions
and
85 deletions
+119
-85
filesource.c
dlls/quartz/filesource.c
+119
-85
No files found.
dlls/quartz/filesource.c
View file @
e0fe0ef0
...
...
@@ -740,28 +740,21 @@ typedef struct DATAREQUEST
IMediaSample
*
pSample
;
/* sample passed to us by user */
DWORD_PTR
dwUserData
;
/* user data passed to us */
OVERLAPPED
ovl
;
/* our overlapped structure */
struct
DATAREQUEST
*
pNext
;
/* next data request in list */
}
DATAREQUEST
;
static
void
queue
(
DATAREQUEST
*
pHead
,
DATAREQUEST
*
pItem
)
{
DATAREQUEST
*
pCurrent
;
for
(
pCurrent
=
pHead
;
pCurrent
->
pNext
;
pCurrent
=
pCurrent
->
pNext
)
;
pCurrent
->
pNext
=
pItem
;
}
typedef
struct
FileAsyncReader
{
OutputPin
pin
;
const
struct
IAsyncReaderVtbl
*
lpVtblAR
;
HANDLE
hFile
;
HANDLE
hEvent
;
BOOL
bFlushing
;
DATAREQUEST
*
pHead
;
/* head of data request list */
CRITICAL_SECTION
csList
;
/* critical section to protect operations on list */
/* Why would you need more? Every sample has its own handle */
LONG
queued_number
;
LONG
samples
;
CRITICAL_SECTION
csList
;
/* critical section to prevent concurrency issues */
DATAREQUEST
*
sample_list
;
HANDLE
*
handle_list
;
}
FileAsyncReader
;
static
inline
FileAsyncReader
*
impl_from_IAsyncReader
(
IAsyncReader
*
iface
)
...
...
@@ -815,20 +808,20 @@ static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface)
{
FileAsyncReader
*
This
=
(
FileAsyncReader
*
)
iface
;
ULONG
refCount
=
InterlockedDecrement
(
&
This
->
pin
.
pin
.
refCount
);
int
x
;
TRACE
(
"(%p)->() Release from %d
\n
"
,
This
,
refCount
+
1
);
if
(
!
refCount
)
{
DATAREQUEST
*
pCurrent
;
DATAREQUEST
*
pNext
;
for
(
pCurrent
=
This
->
pHead
;
pCurrent
;
pCurrent
=
pNext
)
CoTaskMemFree
(
This
->
sample_list
);
if
(
This
->
handle_list
)
{
pNext
=
pCurrent
->
pNext
;
CoTaskMemFree
(
pCurrent
);
for
(
x
=
0
;
x
<
This
->
samples
;
++
x
)
CloseHandle
(
This
->
handle_list
[
x
]);
CoTaskMemFree
(
This
->
handle_list
);
}
CloseHandle
(
This
->
hFile
);
CloseHandle
(
This
->
hEvent
);
This
->
csList
.
DebugInfo
->
Spare
[
0
]
=
0
;
DeleteCriticalSection
(
&
This
->
csList
);
CoTaskMemFree
(
This
);
...
...
@@ -919,9 +912,10 @@ static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter
FileAsyncReader
*
pPinImpl
=
(
FileAsyncReader
*
)
*
ppPin
;
pPinImpl
->
lpVtblAR
=
&
FileAsyncReader_Vtbl
;
pPinImpl
->
hFile
=
hFile
;
pPinImpl
->
hEvent
=
CreateEventW
(
NULL
,
0
,
0
,
NULL
);
pPinImpl
->
bFlushing
=
FALSE
;
pPinImpl
->
pHead
=
NULL
;
pPinImpl
->
sample_list
=
NULL
;
pPinImpl
->
handle_list
=
NULL
;
pPinImpl
->
queued_number
=
0
;
pPinImpl
->
pin
.
pConnectSpecific
=
FileAsyncReaderPin_ConnectSpecific
;
InitializeCriticalSection
(
&
pPinImpl
->
csList
);
pPinImpl
->
csList
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": FileAsyncReader.csList"
);
...
...
@@ -956,6 +950,8 @@ static ULONG WINAPI FileAsyncReader_Release(IAsyncReader * iface)
static
HRESULT
WINAPI
FileAsyncReader_RequestAllocator
(
IAsyncReader
*
iface
,
IMemAllocator
*
pPreferred
,
ALLOCATOR_PROPERTIES
*
pProps
,
IMemAllocator
**
ppActual
)
{
FileAsyncReader
*
This
=
impl_from_IAsyncReader
(
iface
);
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p, %p, %p)
\n
"
,
pPreferred
,
pProps
,
ppActual
);
...
...
@@ -965,15 +961,14 @@ static HRESULT WINAPI FileAsyncReader_RequestAllocator(IAsyncReader * iface, IMe
if
(
pPreferred
)
{
ALLOCATOR_PROPERTIES
PropsActual
;
hr
=
IMemAllocator_SetProperties
(
pPreferred
,
pProps
,
&
PropsActual
);
hr
=
IMemAllocator_SetProperties
(
pPreferred
,
pProps
,
pProps
);
/* FIXME: check we are still aligned */
if
(
SUCCEEDED
(
hr
))
{
IMemAllocator_AddRef
(
pPreferred
);
*
ppActual
=
pPreferred
;
TRACE
(
"FileAsyncReader_RequestAllocator -- %x
\n
"
,
hr
);
return
S_OK
;
goto
done
;
}
}
...
...
@@ -983,14 +978,50 @@ static HRESULT WINAPI FileAsyncReader_RequestAllocator(IAsyncReader * iface, IMe
if
(
SUCCEEDED
(
hr
))
{
ALLOCATOR_PROPERTIES
PropsActual
;
hr
=
IMemAllocator_SetProperties
(
pPreferred
,
pProps
,
&
PropsActual
);
hr
=
IMemAllocator_SetProperties
(
pPreferred
,
pProps
,
pProps
);
/* FIXME: check we are still aligned */
if
(
SUCCEEDED
(
hr
))
{
*
ppActual
=
pPreferred
;
TRACE
(
"FileAsyncReader_RequestAllocator -- %x
\n
"
,
hr
);
return
S_OK
;
}
}
done:
if
(
SUCCEEDED
(
hr
))
{
CoTaskMemFree
(
This
->
sample_list
);
if
(
This
->
handle_list
)
{
int
x
;
for
(
x
=
0
;
x
<
This
->
samples
;
++
x
)
CloseHandle
(
This
->
handle_list
[
x
]);
CoTaskMemFree
(
This
->
handle_list
);
}
This
->
samples
=
pProps
->
cBuffers
;
TRACE
(
"Samples: %u
\n
"
,
This
->
samples
);
This
->
sample_list
=
CoTaskMemAlloc
(
sizeof
(
This
->
sample_list
[
0
])
*
pProps
->
cBuffers
);
This
->
handle_list
=
CoTaskMemAlloc
(
sizeof
(
HANDLE
)
*
pProps
->
cBuffers
);
if
(
This
->
sample_list
&&
This
->
handle_list
)
{
int
x
;
ZeroMemory
(
This
->
sample_list
,
sizeof
(
This
->
sample_list
[
0
])
*
pProps
->
cBuffers
);
for
(
x
=
0
;
x
<
This
->
samples
;
++
x
)
{
This
->
sample_list
[
x
].
ovl
.
hEvent
=
This
->
handle_list
[
x
]
=
CreateEventW
(
NULL
,
0
,
0
,
NULL
);
}
This
->
pin
.
allocProps
=
*
pProps
;
}
else
{
hr
=
E_OUTOFMEMORY
;
CoTaskMemFree
(
This
->
sample_list
);
CoTaskMemFree
(
This
->
handle_list
);
This
->
samples
=
0
;
This
->
sample_list
=
NULL
;
This
->
handle_list
=
NULL
;
}
}
...
...
@@ -1009,21 +1040,16 @@ static HRESULT WINAPI FileAsyncReader_RequestAllocator(IAsyncReader * iface, IMe
* however, this would be quite complicated to do and may be a bit error prone */
static
HRESULT
WINAPI
FileAsyncReader_Request
(
IAsyncReader
*
iface
,
IMediaSample
*
pSample
,
DWORD_PTR
dwUser
)
{
HRESULT
hr
=
S_OK
;
REFERENCE_TIME
Start
;
REFERENCE_TIME
Stop
;
DATAREQUEST
*
pDataRq
;
BYTE
*
pBuffer
;
HRESULT
hr
=
S_OK
;
FileAsyncReader
*
This
=
impl_from_IAsyncReader
(
iface
);
LPBYTE
pBuffer
=
NULL
;
TRACE
(
"(%p, %lx)
\n
"
,
pSample
,
dwUser
);
/* check flushing state */
if
(
This
->
bFlushing
)
return
VFW_E_WRONG_STATE
;
if
(
!
(
pDataRq
=
CoTaskMemAlloc
(
sizeof
(
*
pDataRq
))))
hr
=
E_OUTOFMEMORY
;
if
(
!
pSample
)
return
E_POINTER
;
/* get start and stop positions in bytes */
if
(
SUCCEEDED
(
hr
))
...
...
@@ -1032,30 +1058,38 @@ static HRESULT WINAPI FileAsyncReader_Request(IAsyncReader * iface, IMediaSample
if
(
SUCCEEDED
(
hr
))
hr
=
IMediaSample_GetPointer
(
pSample
,
&
pBuffer
);
EnterCriticalSection
(
&
This
->
csList
);
if
(
This
->
bFlushing
)
{
LeaveCriticalSection
(
&
This
->
csList
);
return
VFW_E_WRONG_STATE
;
}
if
(
SUCCEEDED
(
hr
))
{
DWORD
dwLength
=
(
DWORD
)
BYTES_FROM_MEDIATIME
(
Stop
-
Start
);
DATAREQUEST
*
pDataRq
;
int
x
;
for
(
x
=
0
;
x
<
This
->
samples
;
++
x
)
{
if
(
!
This
->
sample_list
[
x
].
pSample
)
break
;
}
assert
(
x
<
This
->
samples
);
InterlockedIncrement
(
&
This
->
queued_number
);
pDataRq
=
This
->
sample_list
+
x
;
pDataRq
->
ovl
.
u
.
s
.
Offset
=
(
DWORD
)
BYTES_FROM_MEDIATIME
(
Start
);
pDataRq
->
ovl
.
u
.
s
.
OffsetHigh
=
(
DWORD
)(
BYTES_FROM_MEDIATIME
(
Start
)
>>
(
sizeof
(
DWORD
)
*
8
));
pDataRq
->
ovl
.
hEvent
=
This
->
hEvent
;
pDataRq
->
dwUserData
=
dwUser
;
pDataRq
->
pNext
=
NULL
;
/* we violate traditional COM rules here by maintaining
* a reference to the sample, but not calling AddRef, but
* that's what MSDN says to do */
pDataRq
->
pSample
=
pSample
;
EnterCriticalSection
(
&
This
->
csList
);
{
if
(
This
->
pHead
)
/* adds data request to end of list */
queue
(
This
->
pHead
,
pDataRq
);
else
This
->
pHead
=
pDataRq
;
}
LeaveCriticalSection
(
&
This
->
csList
);
/* this is definitely not how it is implemented on Win9x
* as they do not support async reads on files, but it is
* sooo much easier to use this than messing around with threads!
...
...
@@ -1068,21 +1102,7 @@ static HRESULT WINAPI FileAsyncReader_Request(IAsyncReader * iface, IMediaSample
hr
=
S_OK
;
}
if
(
FAILED
(
hr
)
&&
pDataRq
)
{
EnterCriticalSection
(
&
This
->
csList
);
{
DATAREQUEST
*
pCurrent
;
for
(
pCurrent
=
This
->
pHead
;
pCurrent
&&
pCurrent
->
pNext
;
pCurrent
=
pCurrent
->
pNext
)
if
(
pCurrent
->
pNext
==
pDataRq
)
{
pCurrent
->
pNext
=
pDataRq
->
pNext
;
break
;
}
}
LeaveCriticalSection
(
&
This
->
csList
);
CoTaskMemFree
(
pDataRq
);
}
TRACE
(
"-- %x
\n
"
,
hr
);
return
hr
;
...
...
@@ -1091,47 +1111,61 @@ static HRESULT WINAPI FileAsyncReader_Request(IAsyncReader * iface, IMediaSample
static
HRESULT
WINAPI
FileAsyncReader_WaitForNext
(
IAsyncReader
*
iface
,
DWORD
dwTimeout
,
IMediaSample
**
ppSample
,
DWORD_PTR
*
pdwUser
)
{
HRESULT
hr
=
S_OK
;
DWORD
dwBytes
=
0
;
DATAREQUEST
*
pDataRq
=
NULL
;
FileAsyncReader
*
This
=
impl_from_IAsyncReader
(
iface
);
DWORD
buffer
=
~
0
;
TRACE
(
"(%u, %p, %p)
\n
"
,
dwTimeout
,
ppSample
,
pdwUser
);
/* FIXME: we could do with improving this by waiting for an array of event handles
* and then determining which one finished and removing that from the list, otherwise
* we will end up waiting for longer than we should do, if a later request finishes
* before an earlier one */
*
ppSample
=
NULL
;
*
pdwUser
=
0
;
if
(
!
This
->
bFlushing
)
{
if
(
!
This
->
pHead
)
ERR
(
"Called without samples in queue!
\n
"
);
if
(
!
This
->
queued_number
)
{
ERR
(
"Called without samples in queue and not flushing!!
\n
"
);
return
E_FAIL
;
}
/* wait for an object to read, or time out */
buffer
=
WaitForMultipleObjectsEx
(
This
->
samples
,
This
->
handle_list
,
FALSE
,
dwTimeout
,
TRUE
);
/* wait for the read to finish or timeout */
if
(
WaitForSingleObject
(
This
->
hEvent
,
dwTimeout
)
==
WAIT_TIMEOUT
)
if
(
buffer
>=
MAXIMUM_WAIT_OBJECTS
)
{
FIXME
(
"Returned: %u (%08x)
\n
"
,
buffer
,
GetLastError
());
hr
=
VFW_E_TIMEOUT
;
buffer
=
~
0
;
}
else
InterlockedDecrement
(
&
This
->
queued_number
);
}
if
(
SUCCEEDED
(
hr
))
{
EnterCriticalSection
(
&
This
->
csList
);
if
(
This
->
bFlushing
&&
buffer
==
~
0
)
{
for
(
buffer
=
0
;
buffer
<
This
->
samples
;
++
buffer
)
{
pDataRq
=
This
->
pHead
;
if
(
pDataRq
==
NULL
)
if
(
This
->
sample_list
[
buffer
].
pSample
)
break
;
}
if
(
buffer
==
This
->
samples
)
{
assert
(
!
This
->
queued_number
);
hr
=
E_FAIL
;
}
else
This
->
pHead
=
pDataRq
->
pNext
;
{
InterlockedDecrement
(
&
This
->
queued_number
);
hr
=
S_OK
;
}
LeaveCriticalSection
(
&
This
->
csList
);
}
if
(
SUCCEEDED
(
hr
))
{
REFERENCE_TIME
rtStart
,
rtStop
;
REFERENCE_TIME
rtSampleStart
,
rtSampleStop
;
DATAREQUEST
*
pDataRq
=
This
->
sample_list
+
buffer
;
DWORD
dwBytes
=
0
;
/* get any errors */
if
(
!
This
->
bFlushing
&&
!
GetOverlappedResult
(
This
->
hFile
,
&
pDataRq
->
ovl
,
&
dwBytes
,
FALSE
))
...
...
@@ -1165,10 +1199,9 @@ static HRESULT WINAPI FileAsyncReader_WaitForNext(IAsyncReader * iface, DWORD dw
else
assert
(
rtStop
==
rtStart
);
This
->
sample_list
[
buffer
].
pSample
=
NULL
;
}
/* no need to close event handle since we will close it when the pin is destroyed */
CoTaskMemFree
(
pDataRq
);
LeaveCriticalSection
(
&
This
->
csList
);
TRACE
(
"-- %x
\n
"
,
hr
);
return
hr
;
...
...
@@ -1260,11 +1293,10 @@ static HRESULT WINAPI FileAsyncReader_BeginFlush(IAsyncReader * iface)
TRACE
(
"()
\n
"
);
EnterCriticalSection
(
&
This
->
csList
);
This
->
bFlushing
=
TRUE
;
CancelIo
(
This
->
hFile
);
SetEvent
(
This
->
hEvent
);
/* FIXME: free list */
LeaveCriticalSection
(
&
This
->
csList
);
return
S_OK
;
}
...
...
@@ -1275,7 +1307,9 @@ static HRESULT WINAPI FileAsyncReader_EndFlush(IAsyncReader * iface)
TRACE
(
"()
\n
"
);
EnterCriticalSection
(
&
This
->
csList
);
This
->
bFlushing
=
FALSE
;
LeaveCriticalSection
(
&
This
->
csList
);
return
S_OK
;
}
...
...
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