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
1cf021f4
Commit
1cf021f4
authored
May 02, 2019
by
Nikolay Sivov
Committed by
Alexandre Julliard
May 02, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mfplat: Implement async file stream creation API.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
cfe9314b
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
331 additions
and
3 deletions
+331
-3
main.c
dlls/mfplat/main.c
+257
-0
mfplat.spec
dlls/mfplat/mfplat.spec
+3
-3
mfplat.c
dlls/mfplat/tests/mfplat.c
+67
-0
mfapi.h
include/mfapi.h
+4
-0
No files found.
dlls/mfplat/main.c
View file @
1cf021f4
...
...
@@ -6713,3 +6713,260 @@ HRESULT WINAPI MFCreateSystemTimeSource(IMFPresentationTimeSource **time_source)
return
S_OK
;
}
struct
async_create_file
{
IMFAsyncCallback
IMFAsyncCallback_iface
;
LONG
refcount
;
MF_FILE_ACCESSMODE
access_mode
;
MF_FILE_OPENMODE
open_mode
;
MF_FILE_FLAGS
flags
;
WCHAR
*
path
;
};
struct
async_create_file_result
{
struct
list
entry
;
IMFAsyncResult
*
result
;
IMFByteStream
*
stream
;
};
static
struct
list
async_create_file_results
=
LIST_INIT
(
async_create_file_results
);
static
CRITICAL_SECTION
async_create_file_cs
=
{
NULL
,
-
1
,
0
,
0
,
0
,
0
};
static
struct
async_create_file
*
impl_from_create_file_IMFAsyncCallback
(
IMFAsyncCallback
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
async_create_file
,
IMFAsyncCallback_iface
);
}
static
HRESULT
WINAPI
async_create_file_callback_QueryInterface
(
IMFAsyncCallback
*
iface
,
REFIID
riid
,
void
**
obj
)
{
if
(
IsEqualIID
(
riid
,
&
IID_IMFAsyncCallback
)
||
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
obj
=
iface
;
IMFAsyncCallback_AddRef
(
iface
);
return
S_OK
;
}
*
obj
=
NULL
;
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
async_create_file_callback_AddRef
(
IMFAsyncCallback
*
iface
)
{
struct
async_create_file
*
async
=
impl_from_create_file_IMFAsyncCallback
(
iface
);
ULONG
refcount
=
InterlockedIncrement
(
&
async
->
refcount
);
TRACE
(
"%p, refcount %u.
\n
"
,
iface
,
refcount
);
return
refcount
;
}
static
ULONG
WINAPI
async_create_file_callback_Release
(
IMFAsyncCallback
*
iface
)
{
struct
async_create_file
*
async
=
impl_from_create_file_IMFAsyncCallback
(
iface
);
ULONG
refcount
=
InterlockedDecrement
(
&
async
->
refcount
);
TRACE
(
"%p, refcount %u.
\n
"
,
iface
,
refcount
);
if
(
!
refcount
)
{
heap_free
(
async
->
path
);
heap_free
(
async
);
}
return
refcount
;
}
static
HRESULT
WINAPI
async_create_file_callback_GetParameters
(
IMFAsyncCallback
*
iface
,
DWORD
*
flags
,
DWORD
*
queue
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
async_create_file_callback_Invoke
(
IMFAsyncCallback
*
iface
,
IMFAsyncResult
*
result
)
{
struct
async_create_file
*
async
=
impl_from_create_file_IMFAsyncCallback
(
iface
);
IMFAsyncResult
*
caller
;
IMFByteStream
*
stream
;
HRESULT
hr
;
caller
=
(
IMFAsyncResult
*
)
IMFAsyncResult_GetStateNoAddRef
(
result
);
hr
=
MFCreateFile
(
async
->
access_mode
,
async
->
open_mode
,
async
->
flags
,
async
->
path
,
&
stream
);
if
(
SUCCEEDED
(
hr
))
{
struct
async_create_file_result
*
result_item
;
result_item
=
heap_alloc
(
sizeof
(
*
result_item
));
if
(
result_item
)
{
result_item
->
result
=
caller
;
IMFAsyncResult_AddRef
(
caller
);
result_item
->
stream
=
stream
;
IMFByteStream_AddRef
(
stream
);
EnterCriticalSection
(
&
async_create_file_cs
);
list_add_tail
(
&
async_create_file_results
,
&
result_item
->
entry
);
LeaveCriticalSection
(
&
async_create_file_cs
);
}
IMFByteStream_Release
(
stream
);
}
else
IMFAsyncResult_SetStatus
(
caller
,
hr
);
MFInvokeCallback
(
caller
);
return
S_OK
;
}
static
const
IMFAsyncCallbackVtbl
async_create_file_callback_vtbl
=
{
async_create_file_callback_QueryInterface
,
async_create_file_callback_AddRef
,
async_create_file_callback_Release
,
async_create_file_callback_GetParameters
,
async_create_file_callback_Invoke
,
};
static
WCHAR
*
heap_strdupW
(
const
WCHAR
*
str
)
{
WCHAR
*
ret
=
NULL
;
if
(
str
)
{
unsigned
int
size
;
size
=
(
strlenW
(
str
)
+
1
)
*
sizeof
(
WCHAR
);
ret
=
heap_alloc
(
size
);
if
(
ret
)
memcpy
(
ret
,
str
,
size
);
}
return
ret
;
}
/***********************************************************************
* MFBeginCreateFile (mfplat.@)
*/
HRESULT
WINAPI
MFBeginCreateFile
(
MF_FILE_ACCESSMODE
access_mode
,
MF_FILE_OPENMODE
open_mode
,
MF_FILE_FLAGS
flags
,
const
WCHAR
*
path
,
IMFAsyncCallback
*
callback
,
IUnknown
*
state
,
IUnknown
**
cancel_cookie
)
{
struct
async_create_file
*
async
=
NULL
;
IMFAsyncResult
*
caller
,
*
item
=
NULL
;
HRESULT
hr
;
TRACE
(
"%#x, %#x, %#x, %s, %p, %p, %p.
\n
"
,
access_mode
,
open_mode
,
flags
,
debugstr_w
(
path
),
callback
,
state
,
cancel_cookie
);
if
(
cancel_cookie
)
*
cancel_cookie
=
NULL
;
if
(
FAILED
(
hr
=
MFCreateAsyncResult
(
NULL
,
callback
,
state
,
&
caller
)))
return
hr
;
async
=
heap_alloc
(
sizeof
(
*
async
));
if
(
!
async
)
{
hr
=
E_OUTOFMEMORY
;
goto
failed
;
}
async
->
IMFAsyncCallback_iface
.
lpVtbl
=
&
async_create_file_callback_vtbl
;
async
->
refcount
=
1
;
async
->
access_mode
=
access_mode
;
async
->
open_mode
=
open_mode
;
async
->
flags
=
flags
;
async
->
path
=
heap_strdupW
(
path
);
if
(
!
async
->
path
)
{
hr
=
E_OUTOFMEMORY
;
goto
failed
;
}
hr
=
MFCreateAsyncResult
(
NULL
,
&
async
->
IMFAsyncCallback_iface
,
(
IUnknown
*
)
caller
,
&
item
);
if
(
FAILED
(
hr
))
goto
failed
;
if
(
cancel_cookie
)
{
*
cancel_cookie
=
(
IUnknown
*
)
caller
;
IUnknown_AddRef
(
*
cancel_cookie
);
}
hr
=
MFInvokeCallback
(
item
);
failed:
if
(
async
)
IMFAsyncCallback_Release
(
&
async
->
IMFAsyncCallback_iface
);
if
(
item
)
IMFAsyncResult_Release
(
item
);
if
(
caller
)
IMFAsyncResult_Release
(
caller
);
return
hr
;
}
static
HRESULT
async_create_file_pull_result
(
IUnknown
*
unk
,
IMFByteStream
**
stream
)
{
struct
async_create_file_result
*
item
;
HRESULT
hr
=
MF_E_UNEXPECTED
;
IMFAsyncResult
*
result
;
*
stream
=
NULL
;
if
(
FAILED
(
IUnknown_QueryInterface
(
unk
,
&
IID_IMFAsyncResult
,
(
void
**
)
&
result
)))
return
hr
;
EnterCriticalSection
(
&
async_create_file_cs
);
LIST_FOR_EACH_ENTRY
(
item
,
&
async_create_file_results
,
struct
async_create_file_result
,
entry
)
{
if
(
result
==
item
->
result
)
{
*
stream
=
item
->
stream
;
IMFAsyncResult_Release
(
item
->
result
);
list_remove
(
&
item
->
entry
);
heap_free
(
item
);
break
;
}
}
LeaveCriticalSection
(
&
async_create_file_cs
);
if
(
*
stream
)
hr
=
IMFAsyncResult_GetStatus
(
result
);
IMFAsyncResult_Release
(
result
);
return
hr
;
}
/***********************************************************************
* MFEndCreateFile (mfplat.@)
*/
HRESULT
WINAPI
MFEndCreateFile
(
IMFAsyncResult
*
result
,
IMFByteStream
**
stream
)
{
TRACE
(
"%p, %p.
\n
"
,
result
,
stream
);
return
async_create_file_pull_result
((
IUnknown
*
)
result
,
stream
);
}
/***********************************************************************
* MFCancelCreateFile (mfplat.@)
*/
HRESULT
WINAPI
MFCancelCreateFile
(
IUnknown
*
cancel_cookie
)
{
IMFByteStream
*
stream
=
NULL
;
HRESULT
hr
;
TRACE
(
"%p.
\n
"
,
cancel_cookie
);
hr
=
async_create_file_pull_result
(
cancel_cookie
,
&
stream
);
if
(
stream
)
IMFByteStream_Release
(
stream
);
return
hr
;
}
dlls/mfplat/mfplat.spec
View file @
1cf021f4
...
...
@@ -20,14 +20,14 @@
@ stdcall MFAllocateWorkQueueEx(long ptr)
@ stub MFAppendCollection
@ stub MFAverageTimePerFrameToFrameRate
@ st
ub MFBeginCreateFile
@ st
dcall MFBeginCreateFile(long long long wstr ptr ptr ptr)
@ stub MFBeginGetHostByName
@ stub MFBeginRegisterWorkQueueWithMMCSS
@ stub MFBeginUnregisterWorkQueueWithMMCSS
@ stub MFBlockThread
@ stub MFCalculateBitmapImageSize
@ stdcall MFCalculateImageSize(ptr long long ptr)
@ st
ub MFCancelCreateFile
@ st
dcall MFCancelCreateFile(ptr)
@ stdcall MFCancelWorkItem(int64)
@ stdcall MFCompareFullToPartialMediaType(ptr ptr)
@ stub MFCompareSockaddrAddresses
...
...
@@ -79,7 +79,7 @@
@ stub MFDeserializeEvent
@ stub MFDeserializeMediaTypeFromStream
@ stub MFDeserializePresentationDescriptor
@ st
ub MFEndCreateFile
@ st
dcall MFEndCreateFile(ptr ptr)
@ stub MFEndGetHostByName
@ stub MFEndRegisterWorkQueueWithMMCSS
@ stub MFEndUnregisterWorkQueueWithMMCSS
...
...
dlls/mfplat/tests/mfplat.c
View file @
1cf021f4
...
...
@@ -2886,6 +2886,72 @@ static void test_MFCreateWaveFormatExFromMFMediaType(void)
IMFMediaType_Release
(
mediatype
);
}
static
HRESULT
WINAPI
test_create_file_callback_Invoke
(
IMFAsyncCallback
*
iface
,
IMFAsyncResult
*
result
)
{
struct
test_callback
*
callback
=
impl_from_IMFAsyncCallback
(
iface
);
IMFByteStream
*
stream
;
IUnknown
*
object
;
HRESULT
hr
;
ok
(
!!
result
,
"Unexpected result object.
\n
"
);
ok
((
IUnknown
*
)
iface
==
IMFAsyncResult_GetStateNoAddRef
(
result
),
"Unexpected result state.
\n
"
);
hr
=
IMFAsyncResult_GetObject
(
result
,
&
object
);
ok
(
hr
==
E_POINTER
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
MFEndCreateFile
(
result
,
&
stream
);
ok
(
hr
==
S_OK
,
"Failed to get file stream, hr %#x.
\n
"
,
hr
);
IMFByteStream_Release
(
stream
);
SetEvent
(
callback
->
event
);
return
S_OK
;
}
static
const
IMFAsyncCallbackVtbl
test_create_file_callback_vtbl
=
{
testcallback_QueryInterface
,
testcallback_AddRef
,
testcallback_Release
,
testcallback_GetParameters
,
test_create_file_callback_Invoke
,
};
static
void
test_async_create_file
(
void
)
{
struct
test_callback
callback
=
{
{
&
test_create_file_callback_vtbl
}
};
WCHAR
pathW
[
MAX_PATH
],
fileW
[
MAX_PATH
];
IUnknown
*
cancel_cookie
;
HRESULT
hr
;
BOOL
ret
;
hr
=
MFStartup
(
MF_VERSION
,
MFSTARTUP_FULL
);
ok
(
hr
==
S_OK
,
"Fail to start up, hr %#x.
\n
"
,
hr
);
callback
.
event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
NULL
);
GetTempPathW
(
ARRAY_SIZE
(
pathW
),
pathW
);
GetTempFileNameW
(
pathW
,
NULL
,
0
,
fileW
);
hr
=
MFBeginCreateFile
(
MF_ACCESSMODE_READWRITE
,
MF_OPENMODE_DELETE_IF_EXIST
,
MF_FILEFLAGS_NONE
,
fileW
,
&
callback
.
IMFAsyncCallback_iface
,
(
IUnknown
*
)
&
callback
.
IMFAsyncCallback_iface
,
&
cancel_cookie
);
ok
(
hr
==
S_OK
,
"Async create request failed, hr %#x.
\n
"
,
hr
);
ok
(
cancel_cookie
!=
NULL
,
"Unexpected cancellation object.
\n
"
);
WaitForSingleObject
(
callback
.
event
,
INFINITE
);
IUnknown_Release
(
cancel_cookie
);
CloseHandle
(
callback
.
event
);
hr
=
MFShutdown
();
ok
(
hr
==
S_OK
,
"Failed to shut down, hr %#x.
\n
"
,
hr
);
ret
=
DeleteFileW
(
fileW
);
ok
(
ret
,
"Failed to delete test file.
\n
"
);
}
START_TEST
(
mfplat
)
{
CoInitialize
(
NULL
);
...
...
@@ -2920,6 +2986,7 @@ START_TEST(mfplat)
test_attributes_serialization
();
test_wrapped_media_type
();
test_MFCreateWaveFormatExFromMFMediaType
();
test_async_create_file
();
CoUninitialize
();
}
include/mfapi.h
View file @
1cf021f4
...
...
@@ -353,7 +353,10 @@ typedef enum _MFWaveFormatExConvertFlags
HRESULT
WINAPI
MFAddPeriodicCallback
(
MFPERIODICCALLBACK
callback
,
IUnknown
*
context
,
DWORD
*
key
);
HRESULT
WINAPI
MFAllocateWorkQueue
(
DWORD
*
queue
);
HRESULT
WINAPI
MFAllocateWorkQueueEx
(
MFASYNC_WORKQUEUE_TYPE
queue_type
,
DWORD
*
queue
);
HRESULT
WINAPI
MFBeginCreateFile
(
MF_FILE_ACCESSMODE
access_mode
,
MF_FILE_OPENMODE
open_mode
,
MF_FILE_FLAGS
flags
,
const
WCHAR
*
path
,
IMFAsyncCallback
*
callback
,
IUnknown
*
state
,
IUnknown
**
cancel_cookie
);
HRESULT
WINAPI
MFCalculateImageSize
(
REFGUID
subtype
,
UINT32
width
,
UINT32
height
,
UINT32
*
size
);
HRESULT
WINAPI
MFCancelCreateFile
(
IUnknown
*
cancel_cookie
);
HRESULT
WINAPI
MFCancelWorkItem
(
MFWORKITEM_KEY
key
);
BOOL
WINAPI
MFCompareFullToPartialMediaType
(
IMFMediaType
*
full_type
,
IMFMediaType
*
partial_type
);
HRESULT
WINAPI
MFCopyImage
(
BYTE
*
dest
,
LONG
deststride
,
const
BYTE
*
src
,
LONG
srcstride
,
DWORD
width
,
DWORD
lines
);
...
...
@@ -370,6 +373,7 @@ HRESULT WINAPI MFCreateMediaType(IMFMediaType **type);
HRESULT
WINAPI
MFCreateSample
(
IMFSample
**
sample
);
HRESULT
WINAPI
MFCreateMemoryBuffer
(
DWORD
max_length
,
IMFMediaBuffer
**
buffer
);
HRESULT
WINAPI
MFCreateWaveFormatExFromMFMediaType
(
IMFMediaType
*
type
,
WAVEFORMATEX
**
format
,
UINT32
*
size
,
UINT32
flags
);
HRESULT
WINAPI
MFEndCreateFile
(
IMFAsyncResult
*
result
,
IMFByteStream
**
stream
);
void
*
WINAPI
MFHeapAlloc
(
SIZE_T
size
,
ULONG
flags
,
char
*
file
,
int
line
,
EAllocationType
type
);
void
WINAPI
MFHeapFree
(
void
*
ptr
);
HRESULT
WINAPI
MFGetAttributesAsBlob
(
IMFAttributes
*
attributes
,
UINT8
*
buffer
,
UINT
size
);
...
...
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