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
de1dd6cb
Commit
de1dd6cb
authored
Dec 05, 2022
by
Bernhard Kölbl
Committed by
Alexandre Julliard
Jul 06, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mfmediaengine: Add support for inserting video effects.
parent
621d153d
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
114 additions
and
15 deletions
+114
-15
main.c
dlls/mfmediaengine/main.c
+107
-3
mfmediaengine.c
dlls/mfmediaengine/tests/mfmediaengine.c
+7
-12
No files found.
dlls/mfmediaengine/main.c
View file @
de1dd6cb
...
...
@@ -113,6 +113,19 @@ struct rect
float
left
,
top
,
right
,
bottom
;
};
struct
effect
{
IUnknown
*
object
;
BOOL
optional
;
};
struct
effects
{
struct
effect
*
effects
;
size_t
count
;
size_t
capacity
;
};
struct
media_engine
{
IMFMediaEngineEx
IMFMediaEngineEx_iface
;
...
...
@@ -145,6 +158,7 @@ struct media_engine
IMFMediaSource
*
source
;
IMFPresentationDescriptor
*
pd
;
}
presentation
;
struct
effects
video_effects
;
struct
{
LONGLONG
pts
;
...
...
@@ -1018,6 +1032,46 @@ static HRESULT media_engine_create_source_node(IMFMediaSource *source, IMFPresen
return
S_OK
;
}
static
HRESULT
media_engine_create_effects
(
struct
effect
*
effects
,
size_t
count
,
IMFTopologyNode
*
src
,
IMFTopologyNode
*
sink
,
IMFTopology
*
topology
)
{
IMFTopologyNode
*
last
=
src
;
HRESULT
hr
=
S_OK
;
size_t
i
;
IMFTopologyNode_AddRef
(
last
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
IMFTopologyNode
*
node
=
NULL
;
if
(
FAILED
(
hr
=
MFCreateTopologyNode
(
MF_TOPOLOGY_TRANSFORM_NODE
,
&
node
)))
{
WARN
(
"Failed to create transform node, hr %#lx"
,
hr
);
break
;
}
IMFTopologyNode_SetObject
(
node
,
(
IUnknown
*
)
effects
[
i
].
object
);
IMFTopologyNode_SetUINT32
(
node
,
&
MF_TOPONODE_NOSHUTDOWN_ON_REMOVE
,
FALSE
);
if
(
effects
[
i
].
optional
)
IMFTopologyNode_SetUINT32
(
node
,
&
MF_TOPONODE_CONNECT_METHOD
,
MF_CONNECT_AS_OPTIONAL
);
IMFTopology_AddNode
(
topology
,
node
);
IMFTopologyNode_ConnectOutput
(
last
,
0
,
node
,
0
);
IMFTopologyNode_Release
(
last
);
last
=
node
;
}
IMFTopologyNode_Release
(
last
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMFTopologyNode_ConnectOutput
(
last
,
0
,
sink
,
0
);
return
hr
;
}
static
HRESULT
media_engine_create_audio_renderer
(
struct
media_engine
*
engine
,
IMFTopologyNode
**
node
)
{
unsigned
int
category
,
role
;
...
...
@@ -1105,6 +1159,20 @@ static void media_engine_clear_presentation(struct media_engine *engine)
memset
(
&
engine
->
presentation
,
0
,
sizeof
(
engine
->
presentation
));
}
static
void
media_engine_clear_effects
(
struct
effects
*
effects
)
{
size_t
i
;
for
(
i
=
0
;
i
<
effects
->
count
;
++
i
)
{
if
(
effects
->
effects
[
i
].
object
)
IUnknown_Release
(
effects
->
effects
[
i
].
object
);
}
free
(
effects
->
effects
);
memset
(
effects
,
0
,
sizeof
(
*
effects
));
}
static
HRESULT
media_engine_create_topology
(
struct
media_engine
*
engine
,
IMFMediaSource
*
source
)
{
IMFStreamDescriptor
*
sd_audio
=
NULL
,
*
sd_video
=
NULL
;
...
...
@@ -1227,7 +1295,10 @@ static HRESULT media_engine_create_topology(struct media_engine *engine, IMFMedi
{
IMFTopology_AddNode
(
topology
,
video_src
);
IMFTopology_AddNode
(
topology
,
grabber_node
);
IMFTopologyNode_ConnectOutput
(
video_src
,
0
,
grabber_node
,
0
);
if
(
FAILED
(
hr
=
media_engine_create_effects
(
engine
->
video_effects
.
effects
,
engine
->
video_effects
.
count
,
video_src
,
grabber_node
,
topology
)))
WARN
(
"Failed to create video effect nodes, hr %#lx.
\n
"
,
hr
);
}
if
(
SUCCEEDED
(
hr
))
...
...
@@ -1382,6 +1453,7 @@ static void free_media_engine(struct media_engine *engine)
IMFAttributes_Release
(
engine
->
attributes
);
if
(
engine
->
resolver
)
IMFSourceResolver_Release
(
engine
->
resolver
);
media_engine_clear_effects
(
&
engine
->
video_effects
);
media_engine_release_video_frame_resources
(
engine
);
media_engine_clear_presentation
(
engine
);
if
(
engine
->
device_manager
)
...
...
@@ -2587,11 +2659,43 @@ static HRESULT WINAPI media_engine_IsProtected(IMFMediaEngineEx *iface, BOOL *pr
return
E_NOTIMPL
;
}
static
HRESULT
media_engine_insert_effect
(
struct
media_engine
*
engine
,
struct
effects
*
effects
,
IUnknown
*
object
,
BOOL
is_optional
)
{
HRESULT
hr
=
S_OK
;
if
(
engine
->
flags
&
FLAGS_ENGINE_SHUT_DOWN
)
hr
=
MF_E_SHUTDOWN
;
else
if
(
!
mf_array_reserve
((
void
**
)
&
effects
->
effects
,
&
effects
->
capacity
,
effects
->
count
+
1
,
sizeof
(
*
effects
->
effects
)))
{
hr
=
E_OUTOFMEMORY
;
}
else
{
effects
->
effects
[
effects
->
count
].
object
=
object
;
if
(
object
)
{
IUnknown_AddRef
(
effects
->
effects
[
effects
->
count
].
object
);
}
effects
->
effects
[
effects
->
count
].
optional
=
is_optional
;
effects
->
count
++
;
}
return
hr
;
}
static
HRESULT
WINAPI
media_engine_InsertVideoEffect
(
IMFMediaEngineEx
*
iface
,
IUnknown
*
effect
,
BOOL
is_optional
)
{
FIXME
(
"%p, %p, %d stub.
\n
"
,
iface
,
effect
,
is_optional
);
struct
media_engine
*
engine
=
impl_from_IMFMediaEngineEx
(
iface
);
HRESULT
hr
=
S_OK
;
return
E_NOTIMPL
;
TRACE
(
"%p, %p, %d.
\n
"
,
iface
,
effect
,
is_optional
);
EnterCriticalSection
(
&
engine
->
cs
);
hr
=
media_engine_insert_effect
(
engine
,
&
engine
->
video_effects
,
effect
,
is_optional
);
LeaveCriticalSection
(
&
engine
->
cs
);
return
hr
;
}
static
HRESULT
WINAPI
media_engine_InsertAudioEffect
(
IMFMediaEngineEx
*
iface
,
IUnknown
*
effect
,
BOOL
is_optional
)
...
...
dlls/mfmediaengine/tests/mfmediaengine.c
View file @
de1dd6cb
...
...
@@ -1829,17 +1829,12 @@ static void test_video_effect(void)
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
hr
=
IMFMediaEngineEx_InsertVideoEffect
(
media_engine_ex
,
(
IUnknown
*
)
&
video_effect
->
IMFTransform_iface
,
FALSE
);
todo_wine
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
EXPECT_REF
(
&
video_effect
->
IMFTransform_iface
,
2
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
EXPECT_REF
(
&
video_effect
->
IMFTransform_iface
,
2
);
hr
=
IMFMediaEngineEx_InsertVideoEffect
(
media_engine_ex
,
(
IUnknown
*
)
&
video_effect2
->
IMFTransform_iface
,
FALSE
);
todo_wine
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
EXPECT_REF
(
&
video_effect2
->
IMFTransform_iface
,
2
);
if
(
FAILED
(
hr
))
{
goto
done
;
}
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
EXPECT_REF
(
&
video_effect2
->
IMFTransform_iface
,
2
);
url
=
SysAllocString
(
L"i420-64x64.avi"
);
hr
=
IMFMediaEngineEx_SetSourceFromByteStream
(
media_engine_ex
,
stream
,
url
);
...
...
@@ -1869,7 +1864,7 @@ done:
IMFMediaEngineEx_Shutdown
(
media_engine_ex
);
ref
=
IMFMediaEngineEx_Release
(
media_engine_ex
);
ok
(
!
ref
,
"Unexpected ref %lu.
\n
"
,
ref
);
todo_wine
ok
(
!
ref
,
"Unexpected ref %lu.
\n
"
,
ref
);
}
if
(
texture
)
...
...
@@ -1880,12 +1875,12 @@ done:
if
(
video_effect2
)
{
ref
=
IMFTransform_Release
(
&
video_effect2
->
IMFTransform_iface
);
ok
(
!
ref
,
"Unexpected ref %lu.
\n
"
,
ref
);
todo_wine
ok
(
!
ref
,
"Unexpected ref %lu.
\n
"
,
ref
);
}
if
(
video_effect
)
{
ref
=
IMFTransform_Release
(
&
video_effect
->
IMFTransform_iface
);
ok
(
!
ref
,
"Unexpected ref %lu.
\n
"
,
ref
);
todo_wine
ok
(
!
ref
,
"Unexpected ref %lu.
\n
"
,
ref
);
}
IMFMediaEngineNotify_Release
(
&
notify
->
IMFMediaEngineNotify_iface
);
...
...
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