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
44c49b23
Commit
44c49b23
authored
May 20, 2023
by
Ziqing Hui
Committed by
Alexandre Julliard
Aug 14, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winegstreamer: Add stubs for stream sink.
parent
0aeab6b7
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
267 additions
and
3 deletions
+267
-3
media_sink.c
dlls/winegstreamer/media_sink.c
+267
-3
No files found.
dlls/winegstreamer/media_sink.c
View file @
44c49b23
...
...
@@ -19,11 +19,25 @@
#include "gst_private.h"
#include "mferror.h"
#include "mfapi.h"
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
mfplat
);
struct
stream_sink
{
IMFStreamSink
IMFStreamSink_iface
;
LONG
refcount
;
DWORD
id
;
IMFMediaType
*
type
;
IMFFinalizableMediaSink
*
media_sink
;
struct
list
entry
;
};
struct
media_sink
{
IMFFinalizableMediaSink
IMFFinalizableMediaSink_iface
;
...
...
@@ -32,13 +46,208 @@ struct media_sink
bool
shutdown
;
IMFByteStream
*
bytestream
;
struct
list
stream_sinks
;
};
static
struct
stream_sink
*
impl_from_IMFStreamSink
(
IMFStreamSink
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
stream_sink
,
IMFStreamSink_iface
);
}
static
struct
media_sink
*
impl_from_IMFFinalizableMediaSink
(
IMFFinalizableMediaSink
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
media_sink
,
IMFFinalizableMediaSink_iface
);
}
static
HRESULT
WINAPI
stream_sink_QueryInterface
(
IMFStreamSink
*
iface
,
REFIID
riid
,
void
**
obj
)
{
struct
stream_sink
*
stream_sink
=
impl_from_IMFStreamSink
(
iface
);
TRACE
(
"iface %p, riid %s, obj %p.
\n
"
,
iface
,
debugstr_guid
(
riid
),
obj
);
if
(
IsEqualIID
(
riid
,
&
IID_IMFStreamSink
)
||
IsEqualGUID
(
riid
,
&
IID_IMFMediaEventGenerator
)
||
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
obj
=
&
stream_sink
->
IMFStreamSink_iface
;
}
else
{
WARN
(
"Unsupported interface %s.
\n
"
,
debugstr_guid
(
riid
));
*
obj
=
NULL
;
return
E_NOINTERFACE
;
}
IUnknown_AddRef
((
IUnknown
*
)
*
obj
);
return
S_OK
;
}
static
ULONG
WINAPI
stream_sink_AddRef
(
IMFStreamSink
*
iface
)
{
struct
stream_sink
*
stream_sink
=
impl_from_IMFStreamSink
(
iface
);
ULONG
refcount
=
InterlockedIncrement
(
&
stream_sink
->
refcount
);
TRACE
(
"iface %p, refcount %lu.
\n
"
,
iface
,
refcount
);
return
refcount
;
}
static
ULONG
WINAPI
stream_sink_Release
(
IMFStreamSink
*
iface
)
{
struct
stream_sink
*
stream_sink
=
impl_from_IMFStreamSink
(
iface
);
ULONG
refcount
=
InterlockedDecrement
(
&
stream_sink
->
refcount
);
TRACE
(
"iface %p, refcount %lu.
\n
"
,
iface
,
refcount
);
if
(
!
refcount
)
{
IMFFinalizableMediaSink_Release
(
stream_sink
->
media_sink
);
if
(
stream_sink
->
type
)
IMFMediaType_Release
(
stream_sink
->
type
);
free
(
stream_sink
);
}
return
refcount
;
}
static
HRESULT
WINAPI
stream_sink_GetEvent
(
IMFStreamSink
*
iface
,
DWORD
flags
,
IMFMediaEvent
**
event
)
{
FIXME
(
"iface %p, flags %#lx, event %p.
\n
"
,
iface
,
flags
,
event
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
stream_sink_BeginGetEvent
(
IMFStreamSink
*
iface
,
IMFAsyncCallback
*
callback
,
IUnknown
*
state
)
{
FIXME
(
"iface %p, callback %p, state %p.
\n
"
,
iface
,
callback
,
state
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
stream_sink_EndGetEvent
(
IMFStreamSink
*
iface
,
IMFAsyncResult
*
result
,
IMFMediaEvent
**
event
)
{
FIXME
(
"iface %p, result %p, event %p.
\n
"
,
iface
,
result
,
event
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
stream_sink_QueueEvent
(
IMFStreamSink
*
iface
,
MediaEventType
event_type
,
REFGUID
ext_type
,
HRESULT
hr
,
const
PROPVARIANT
*
value
)
{
FIXME
(
"iface %p, event_type %lu, ext_type %s, hr %#lx, value %p.
\n
"
,
iface
,
event_type
,
debugstr_guid
(
ext_type
),
hr
,
value
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
stream_sink_GetMediaSink
(
IMFStreamSink
*
iface
,
IMFMediaSink
**
ret
)
{
struct
stream_sink
*
stream_sink
=
impl_from_IMFStreamSink
(
iface
);
TRACE
(
"iface %p, ret %p.
\n
"
,
iface
,
ret
);
IMFMediaSink_AddRef
((
*
ret
=
(
IMFMediaSink
*
)
stream_sink
->
media_sink
));
return
S_OK
;
}
static
HRESULT
WINAPI
stream_sink_GetIdentifier
(
IMFStreamSink
*
iface
,
DWORD
*
identifier
)
{
struct
stream_sink
*
stream_sink
=
impl_from_IMFStreamSink
(
iface
);
TRACE
(
"iface %p, identifier %p.
\n
"
,
iface
,
identifier
);
*
identifier
=
stream_sink
->
id
;
return
S_OK
;
}
static
HRESULT
WINAPI
stream_sink_GetMediaTypeHandler
(
IMFStreamSink
*
iface
,
IMFMediaTypeHandler
**
handler
)
{
FIXME
(
"iface %p, handler %p stub!
\n
"
,
iface
,
handler
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
stream_sink_ProcessSample
(
IMFStreamSink
*
iface
,
IMFSample
*
sample
)
{
FIXME
(
"iface %p, sample %p stub!
\n
"
,
iface
,
sample
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
stream_sink_PlaceMarker
(
IMFStreamSink
*
iface
,
MFSTREAMSINK_MARKER_TYPE
marker_type
,
const
PROPVARIANT
*
marker_value
,
const
PROPVARIANT
*
context_value
)
{
FIXME
(
"iface %p, marker_type %d, marker_value %p, context_value %p stub!
\n
"
,
iface
,
marker_type
,
marker_value
,
context_value
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
stream_sink_Flush
(
IMFStreamSink
*
iface
)
{
FIXME
(
"iface %p stub!
\n
"
,
iface
);
return
E_NOTIMPL
;
}
static
const
IMFStreamSinkVtbl
stream_sink_vtbl
=
{
stream_sink_QueryInterface
,
stream_sink_AddRef
,
stream_sink_Release
,
stream_sink_GetEvent
,
stream_sink_BeginGetEvent
,
stream_sink_EndGetEvent
,
stream_sink_QueueEvent
,
stream_sink_GetMediaSink
,
stream_sink_GetIdentifier
,
stream_sink_GetMediaTypeHandler
,
stream_sink_ProcessSample
,
stream_sink_PlaceMarker
,
stream_sink_Flush
,
};
static
HRESULT
stream_sink_create
(
DWORD
stream_sink_id
,
IMFMediaType
*
media_type
,
struct
media_sink
*
media_sink
,
struct
stream_sink
**
out
)
{
struct
stream_sink
*
stream_sink
;
TRACE
(
"stream_sink_id %#lx, media_type %p, media_sink %p, out %p.
\n
"
,
stream_sink_id
,
media_type
,
media_sink
,
out
);
if
(
!
(
stream_sink
=
calloc
(
1
,
sizeof
(
*
stream_sink
))))
return
E_OUTOFMEMORY
;
stream_sink
->
IMFStreamSink_iface
.
lpVtbl
=
&
stream_sink_vtbl
;
stream_sink
->
refcount
=
1
;
stream_sink
->
id
=
stream_sink_id
;
if
(
media_type
)
IMFMediaType_AddRef
((
stream_sink
->
type
=
media_type
));
IMFFinalizableMediaSink_AddRef
((
stream_sink
->
media_sink
=
&
media_sink
->
IMFFinalizableMediaSink_iface
));
TRACE
(
"Created stream sink %p.
\n
"
,
stream_sink
);
*
out
=
stream_sink
;
return
S_OK
;
}
static
struct
stream_sink
*
media_sink_get_stream_sink_by_id
(
struct
media_sink
*
media_sink
,
DWORD
id
)
{
struct
stream_sink
*
stream_sink
;
LIST_FOR_EACH_ENTRY
(
stream_sink
,
&
media_sink
->
stream_sinks
,
struct
stream_sink
,
entry
)
{
if
(
stream_sink
->
id
==
id
)
return
stream_sink
;
}
return
NULL
;
}
static
HRESULT
WINAPI
media_sink_QueryInterface
(
IMFFinalizableMediaSink
*
iface
,
REFIID
riid
,
void
**
obj
)
{
TRACE
(
"iface %p, riid %s, obj %p.
\n
"
,
iface
,
debugstr_guid
(
riid
),
obj
);
...
...
@@ -98,10 +307,36 @@ static HRESULT WINAPI media_sink_GetCharacteristics(IMFFinalizableMediaSink *ifa
static
HRESULT
WINAPI
media_sink_AddStreamSink
(
IMFFinalizableMediaSink
*
iface
,
DWORD
stream_sink_id
,
IMFMediaType
*
media_type
,
IMFStreamSink
**
stream_sink
)
{
FIXME
(
"iface %p, stream_sink_id %#lx, media_type %p, stream_sink %p stub!
\n
"
,
struct
media_sink
*
media_sink
=
impl_from_IMFFinalizableMediaSink
(
iface
);
struct
stream_sink
*
object
;
HRESULT
hr
;
TRACE
(
"iface %p, stream_sink_id %#lx, media_type %p, stream_sink %p.
\n
"
,
iface
,
stream_sink_id
,
media_type
,
stream_sink
);
return
E_NOTIMPL
;
EnterCriticalSection
(
&
media_sink
->
cs
);
if
(
media_sink_get_stream_sink_by_id
(
media_sink
,
stream_sink_id
))
{
LeaveCriticalSection
(
&
media_sink
->
cs
);
return
MF_E_STREAMSINK_EXISTS
;
}
if
(
FAILED
(
hr
=
stream_sink_create
(
stream_sink_id
,
media_type
,
media_sink
,
&
object
)))
{
WARN
(
"Failed to create stream sink, hr %#lx.
\n
"
,
hr
);
LeaveCriticalSection
(
&
media_sink
->
cs
);
return
hr
;
}
list_add_tail
(
&
media_sink
->
stream_sinks
,
&
object
->
entry
);
LeaveCriticalSection
(
&
media_sink
->
cs
);
if
(
stream_sink
)
IMFStreamSink_AddRef
((
*
stream_sink
=
&
object
->
IMFStreamSink_iface
));
return
S_OK
;
}
static
HRESULT
WINAPI
media_sink_RemoveStreamSink
(
IMFFinalizableMediaSink
*
iface
,
DWORD
stream_sink_id
)
...
...
@@ -151,6 +386,7 @@ static HRESULT WINAPI media_sink_GetPresentationClock(IMFFinalizableMediaSink *i
static
HRESULT
WINAPI
media_sink_Shutdown
(
IMFFinalizableMediaSink
*
iface
)
{
struct
media_sink
*
media_sink
=
impl_from_IMFFinalizableMediaSink
(
iface
);
struct
stream_sink
*
stream_sink
,
*
next
;
TRACE
(
"iface %p.
\n
"
,
iface
);
...
...
@@ -162,6 +398,12 @@ static HRESULT WINAPI media_sink_Shutdown(IMFFinalizableMediaSink *iface)
return
MF_E_SHUTDOWN
;
}
LIST_FOR_EACH_ENTRY_SAFE
(
stream_sink
,
next
,
&
media_sink
->
stream_sinks
,
struct
stream_sink
,
entry
)
{
list_remove
(
&
stream_sink
->
entry
);
IMFStreamSink_Release
(
&
stream_sink
->
IMFStreamSink_iface
);
}
IMFByteStream_Close
(
media_sink
->
bytestream
);
media_sink
->
shutdown
=
TRUE
;
...
...
@@ -220,6 +462,7 @@ static HRESULT media_sink_create(IMFByteStream *bytestream, struct media_sink **
InitializeCriticalSection
(
&
media_sink
->
cs
);
media_sink
->
cs
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": cs"
);
IMFByteStream_AddRef
((
media_sink
->
bytestream
=
bytestream
));
list_init
(
&
media_sink
->
stream_sinks
);
*
out
=
media_sink
;
TRACE
(
"Created media sink %p.
\n
"
,
media_sink
);
...
...
@@ -254,6 +497,7 @@ static ULONG WINAPI sink_class_factory_Release(IMFSinkClassFactory *iface)
static
HRESULT
WINAPI
sink_class_factory_CreateMediaSink
(
IMFSinkClassFactory
*
iface
,
IMFByteStream
*
bytestream
,
IMFMediaType
*
video_type
,
IMFMediaType
*
audio_type
,
IMFMediaSink
**
out
)
{
IMFFinalizableMediaSink
*
media_sink_iface
;
struct
media_sink
*
media_sink
;
HRESULT
hr
;
...
...
@@ -262,8 +506,28 @@ static HRESULT WINAPI sink_class_factory_CreateMediaSink(IMFSinkClassFactory *if
if
(
FAILED
(
hr
=
media_sink_create
(
bytestream
,
&
media_sink
)))
return
hr
;
media_sink_iface
=
&
media_sink
->
IMFFinalizableMediaSink_iface
;
if
(
video_type
)
{
if
(
FAILED
(
hr
=
IMFFinalizableMediaSink_AddStreamSink
(
media_sink_iface
,
1
,
video_type
,
NULL
)))
{
IMFFinalizableMediaSink_Shutdown
(
media_sink_iface
);
IMFFinalizableMediaSink_Release
(
media_sink_iface
);
return
hr
;
}
}
if
(
audio_type
)
{
if
(
FAILED
(
hr
=
IMFFinalizableMediaSink_AddStreamSink
(
media_sink_iface
,
2
,
audio_type
,
NULL
)))
{
IMFFinalizableMediaSink_Shutdown
(
media_sink_iface
);
IMFFinalizableMediaSink_Release
(
media_sink_iface
);
return
hr
;
}
}
*
out
=
(
IMFMediaSink
*
)
&
media_sink
->
IMFFinalizableMediaS
ink_iface
;
*
out
=
(
IMFMediaSink
*
)
media_s
ink_iface
;
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