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
7cee5e55
Commit
7cee5e55
authored
Sep 25, 2023
by
Ziqing Hui
Committed by
Alexandre Julliard
Nov 06, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winegstreamer: Implement wg_muxer_start.
parent
29a8faf1
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
159 additions
and
30 deletions
+159
-30
gst_private.h
dlls/winegstreamer/gst_private.h
+1
-0
main.c
dlls/winegstreamer/main.c
+15
-0
media_sink.c
dlls/winegstreamer/media_sink.c
+8
-1
unix_private.h
dlls/winegstreamer/unix_private.h
+1
-0
unixlib.h
dlls/winegstreamer/unixlib.h
+1
-0
wg_muxer.c
dlls/winegstreamer/wg_muxer.c
+131
-29
wg_parser.c
dlls/winegstreamer/wg_parser.c
+2
-0
No files found.
dlls/winegstreamer/gst_private.h
View file @
7cee5e55
...
@@ -113,6 +113,7 @@ HRESULT wg_transform_flush(wg_transform_t transform);
...
@@ -113,6 +113,7 @@ HRESULT wg_transform_flush(wg_transform_t transform);
HRESULT
wg_muxer_create
(
const
char
*
format
,
wg_muxer_t
*
muxer
);
HRESULT
wg_muxer_create
(
const
char
*
format
,
wg_muxer_t
*
muxer
);
void
wg_muxer_destroy
(
wg_muxer_t
muxer
);
void
wg_muxer_destroy
(
wg_muxer_t
muxer
);
HRESULT
wg_muxer_add_stream
(
wg_muxer_t
muxer
,
UINT32
stream_id
,
const
struct
wg_format
*
format
);
HRESULT
wg_muxer_add_stream
(
wg_muxer_t
muxer
,
UINT32
stream_id
,
const
struct
wg_format
*
format
);
HRESULT
wg_muxer_start
(
wg_muxer_t
muxer
);
unsigned
int
wg_format_get_bytes_for_uncompressed
(
wg_video_format
format
,
unsigned
int
width
,
unsigned
int
height
);
unsigned
int
wg_format_get_bytes_for_uncompressed
(
wg_video_format
format
,
unsigned
int
width
,
unsigned
int
height
);
unsigned
int
wg_format_get_max_size
(
const
struct
wg_format
*
format
);
unsigned
int
wg_format_get_max_size
(
const
struct
wg_format
*
format
);
...
...
dlls/winegstreamer/main.c
View file @
7cee5e55
...
@@ -508,6 +508,21 @@ HRESULT wg_muxer_add_stream(wg_muxer_t muxer, UINT32 stream_id, const struct wg_
...
@@ -508,6 +508,21 @@ HRESULT wg_muxer_add_stream(wg_muxer_t muxer, UINT32 stream_id, const struct wg_
return
S_OK
;
return
S_OK
;
}
}
HRESULT
wg_muxer_start
(
wg_muxer_t
muxer
)
{
NTSTATUS
status
;
TRACE
(
"muxer %#I64x.
\n
"
,
muxer
);
if
((
status
=
WINE_UNIX_CALL
(
unix_wg_muxer_start
,
&
muxer
)))
{
WARN
(
"Failed to start muxer, status %#lx.
\n
"
,
status
);
return
HRESULT_FROM_NT
(
status
);
}
return
S_OK
;
}
#define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1))
#define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1))
unsigned
int
wg_format_get_stride
(
const
struct
wg_format
*
format
)
unsigned
int
wg_format_get_stride
(
const
struct
wg_format
*
format
)
...
...
dlls/winegstreamer/media_sink.c
View file @
7cee5e55
...
@@ -498,7 +498,13 @@ static HRESULT media_sink_queue_stream_event(struct media_sink *media_sink, Medi
...
@@ -498,7 +498,13 @@ static HRESULT media_sink_queue_stream_event(struct media_sink *media_sink, Medi
static
HRESULT
media_sink_start
(
struct
media_sink
*
media_sink
)
static
HRESULT
media_sink_start
(
struct
media_sink
*
media_sink
)
{
{
HRESULT
hr
;
if
(
FAILED
(
hr
=
wg_muxer_start
(
media_sink
->
muxer
)))
return
hr
;
media_sink
->
state
=
STATE_STARTED
;
media_sink
->
state
=
STATE_STARTED
;
return
media_sink_queue_stream_event
(
media_sink
,
MEStreamSinkStarted
);
return
media_sink_queue_stream_event
(
media_sink
,
MEStreamSinkStarted
);
}
}
...
@@ -1007,7 +1013,8 @@ static HRESULT WINAPI media_sink_callback_Invoke(IMFAsyncCallback *iface, IMFAsy
...
@@ -1007,7 +1013,8 @@ static HRESULT WINAPI media_sink_callback_Invoke(IMFAsyncCallback *iface, IMFAsy
switch
(
command
->
op
)
switch
(
command
->
op
)
{
{
case
ASYNC_START
:
case
ASYNC_START
:
hr
=
media_sink_start
(
media_sink
);
if
(
FAILED
(
hr
=
media_sink_start
(
media_sink
)))
WARN
(
"Failed to start media sink.
\n
"
);
break
;
break
;
case
ASYNC_STOP
:
case
ASYNC_STOP
:
hr
=
media_sink_stop
(
media_sink
);
hr
=
media_sink_stop
(
media_sink
);
...
...
dlls/winegstreamer/unix_private.h
View file @
7cee5e55
...
@@ -68,6 +68,7 @@ extern NTSTATUS wg_transform_flush(void *args) DECLSPEC_HIDDEN;
...
@@ -68,6 +68,7 @@ extern NTSTATUS wg_transform_flush(void *args) DECLSPEC_HIDDEN;
extern
NTSTATUS
wg_muxer_create
(
void
*
args
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
wg_muxer_create
(
void
*
args
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
wg_muxer_destroy
(
void
*
args
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
wg_muxer_destroy
(
void
*
args
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
wg_muxer_add_stream
(
void
*
args
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
wg_muxer_add_stream
(
void
*
args
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
wg_muxer_start
(
void
*
args
)
DECLSPEC_HIDDEN
;
/* wg_allocator.c */
/* wg_allocator.c */
...
...
dlls/winegstreamer/unixlib.h
View file @
7cee5e55
...
@@ -428,6 +428,7 @@ enum unix_funcs
...
@@ -428,6 +428,7 @@ enum unix_funcs
unix_wg_muxer_create
,
unix_wg_muxer_create
,
unix_wg_muxer_destroy
,
unix_wg_muxer_destroy
,
unix_wg_muxer_add_stream
,
unix_wg_muxer_add_stream
,
unix_wg_muxer_start
,
unix_wg_funcs_count
,
unix_wg_funcs_count
,
};
};
...
...
dlls/winegstreamer/wg_muxer.c
View file @
7cee5e55
...
@@ -18,6 +18,27 @@
...
@@ -18,6 +18,27 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
*/
/*
* wg_muxer will autoplug gstreamer muxer and parser elements.
* It creates a pipeline like this:
*
* ------------------- -------
* [my_src 1] ==> |parser 1 (optional)| ==> | |
* ------------------- | |
* | |
* ------------------- | |
* [my_src 2] ==> |parser 2 (optional)| ==> | |
* ------------------- | |
* | muxer | ==> [my_sink]
* | |
* [ ...... ] | |
* | |
* | |
* ------------------- | |
* [my_src n] ==> |parser n (optional)| ==> | |
* ------------------- -------
*/
#if 0
#if 0
#pragma makedep unix
#pragma makedep unix
#endif
#endif
...
@@ -36,6 +57,8 @@ struct wg_muxer
...
@@ -36,6 +57,8 @@ struct wg_muxer
{
{
GstElement
*
container
,
*
muxer
;
GstElement
*
container
,
*
muxer
;
GstPad
*
my_sink
;
GstPad
*
my_sink
;
GstCaps
*
my_sink_caps
;
struct
list
streams
;
struct
list
streams
;
};
};
...
@@ -48,6 +71,7 @@ struct wg_muxer_stream
...
@@ -48,6 +71,7 @@ struct wg_muxer_stream
GstPad
*
my_src
;
GstPad
*
my_src
;
GstCaps
*
my_src_caps
,
*
parser_src_caps
;
GstCaps
*
my_src_caps
,
*
parser_src_caps
;
GstElement
*
parser
;
GstElement
*
parser
;
GstSegment
segment
;
struct
list
entry
;
struct
list
entry
;
};
};
...
@@ -57,6 +81,53 @@ static struct wg_muxer *get_muxer(wg_muxer_t muxer)
...
@@ -57,6 +81,53 @@ static struct wg_muxer *get_muxer(wg_muxer_t muxer)
return
(
struct
wg_muxer
*
)(
ULONG_PTR
)
muxer
;
return
(
struct
wg_muxer
*
)(
ULONG_PTR
)
muxer
;
}
}
static
bool
muxer_try_muxer_factory
(
struct
wg_muxer
*
muxer
,
GstElementFactory
*
muxer_factory
)
{
struct
wg_muxer_stream
*
stream
;
GST_INFO
(
"Trying %"
GST_PTR_FORMAT
"."
,
muxer_factory
);
LIST_FOR_EACH_ENTRY
(
stream
,
&
muxer
->
streams
,
struct
wg_muxer_stream
,
entry
)
{
GstCaps
*
caps
=
stream
->
parser
?
stream
->
parser_src_caps
:
stream
->
my_src_caps
;
if
(
!
gst_element_factory_can_sink_any_caps
(
muxer_factory
,
caps
))
{
GST_INFO
(
"%"
GST_PTR_FORMAT
" cannot sink stream %u %p, caps %"
GST_PTR_FORMAT
,
muxer_factory
,
stream
->
id
,
stream
,
caps
);
return
false
;
}
}
return
true
;
}
static
GstElement
*
muxer_find_muxer
(
struct
wg_muxer
*
muxer
)
{
/* Some muxers are formatter, eg. id3mux. */
GstElementFactoryListType
muxer_type
=
GST_ELEMENT_FACTORY_TYPE_MUXER
|
GST_ELEMENT_FACTORY_TYPE_FORMATTER
;
GstElement
*
element
=
NULL
;
GList
*
muxers
,
*
tmp
;
GST_DEBUG
(
"muxer %p."
,
muxer
);
muxers
=
find_element_factories
(
muxer_type
,
GST_RANK_NONE
,
NULL
,
muxer
->
my_sink_caps
);
for
(
tmp
=
muxers
;
tmp
&&
!
element
;
tmp
=
tmp
->
next
)
{
GstElementFactory
*
factory
=
GST_ELEMENT_FACTORY
(
tmp
->
data
);
if
(
muxer_try_muxer_factory
(
muxer
,
factory
))
element
=
factory_create_element
(
factory
);
}
gst_plugin_feature_list_free
(
muxers
);
if
(
!
element
)
GST_WARNING
(
"Failed to find any compatible muxer element."
);
return
element
;
}
static
gboolean
muxer_sink_query_cb
(
GstPad
*
pad
,
GstObject
*
parent
,
GstQuery
*
query
)
static
gboolean
muxer_sink_query_cb
(
GstPad
*
pad
,
GstObject
*
parent
,
GstQuery
*
query
)
{
{
struct
wg_muxer
*
muxer
=
gst_pad_get_element_private
(
pad
);
struct
wg_muxer
*
muxer
=
gst_pad_get_element_private
(
pad
);
...
@@ -87,10 +158,8 @@ static void stream_free(struct wg_muxer_stream *stream)
...
@@ -87,10 +158,8 @@ static void stream_free(struct wg_muxer_stream *stream)
NTSTATUS
wg_muxer_create
(
void
*
args
)
NTSTATUS
wg_muxer_create
(
void
*
args
)
{
{
struct
wg_muxer_create_params
*
params
=
args
;
struct
wg_muxer_create_params
*
params
=
args
;
GstElement
*
first
=
NULL
,
*
last
=
NULL
;
NTSTATUS
status
=
STATUS_UNSUCCESSFUL
;
NTSTATUS
status
=
STATUS_UNSUCCESSFUL
;
GstPadTemplate
*
template
=
NULL
;
GstPadTemplate
*
template
=
NULL
;
GstCaps
*
sink_caps
=
NULL
;
struct
wg_muxer
*
muxer
;
struct
wg_muxer
*
muxer
;
/* Create wg_muxer object. */
/* Create wg_muxer object. */
...
@@ -101,12 +170,12 @@ NTSTATUS wg_muxer_create(void *args)
...
@@ -101,12 +170,12 @@ NTSTATUS wg_muxer_create(void *args)
goto
out
;
goto
out
;
/* Create sink pad. */
/* Create sink pad. */
if
(
!
(
sink_caps
=
gst_caps_from_string
(
params
->
format
)))
if
(
!
(
muxer
->
my_
sink_caps
=
gst_caps_from_string
(
params
->
format
)))
{
{
GST_ERROR
(
"Failed to get caps from format string:
\"
%s
\"
."
,
params
->
format
);
GST_ERROR
(
"Failed to get caps from format string:
\"
%s
\"
."
,
params
->
format
);
goto
out
;
goto
out
;
}
}
if
(
!
(
template
=
gst_pad_template_new
(
"sink"
,
GST_PAD_SINK
,
GST_PAD_ALWAYS
,
sink_caps
)))
if
(
!
(
template
=
gst_pad_template_new
(
"sink"
,
GST_PAD_SINK
,
GST_PAD_ALWAYS
,
muxer
->
my_
sink_caps
)))
goto
out
;
goto
out
;
muxer
->
my_sink
=
gst_pad_new_from_template
(
template
,
"wg_muxer_sink"
);
muxer
->
my_sink
=
gst_pad_new_from_template
(
template
,
"wg_muxer_sink"
);
if
(
!
muxer
->
my_sink
)
if
(
!
muxer
->
my_sink
)
...
@@ -114,26 +183,7 @@ NTSTATUS wg_muxer_create(void *args)
...
@@ -114,26 +183,7 @@ NTSTATUS wg_muxer_create(void *args)
gst_pad_set_element_private
(
muxer
->
my_sink
,
muxer
);
gst_pad_set_element_private
(
muxer
->
my_sink
,
muxer
);
gst_pad_set_query_function
(
muxer
->
my_sink
,
muxer_sink_query_cb
);
gst_pad_set_query_function
(
muxer
->
my_sink
,
muxer_sink_query_cb
);
/* Create gstreamer muxer element. */
if
(
!
(
muxer
->
muxer
=
find_element
(
GST_ELEMENT_FACTORY_TYPE_MUXER
|
GST_ELEMENT_FACTORY_TYPE_FORMATTER
,
NULL
,
sink_caps
)))
goto
out
;
if
(
!
append_element
(
muxer
->
container
,
muxer
->
muxer
,
&
first
,
&
last
))
goto
out
;
/* Link muxer to sink pad. */
if
(
!
link_element_to_sink
(
muxer
->
muxer
,
muxer
->
my_sink
))
goto
out
;
if
(
!
gst_pad_set_active
(
muxer
->
my_sink
,
1
))
goto
out
;
/* Set to pause state. */
gst_element_set_state
(
muxer
->
container
,
GST_STATE_PAUSED
);
if
(
!
gst_element_get_state
(
muxer
->
container
,
NULL
,
NULL
,
-
1
))
goto
out
;
gst_object_unref
(
template
);
gst_object_unref
(
template
);
gst_caps_unref
(
sink_caps
);
GST_INFO
(
"Created winegstreamer muxer %p."
,
muxer
);
GST_INFO
(
"Created winegstreamer muxer %p."
,
muxer
);
params
->
muxer
=
(
wg_transform_t
)(
ULONG_PTR
)
muxer
;
params
->
muxer
=
(
wg_transform_t
)(
ULONG_PTR
)
muxer
;
...
@@ -145,13 +195,10 @@ out:
...
@@ -145,13 +195,10 @@ out:
gst_object_unref
(
muxer
->
my_sink
);
gst_object_unref
(
muxer
->
my_sink
);
if
(
template
)
if
(
template
)
gst_object_unref
(
template
);
gst_object_unref
(
template
);
if
(
sink_caps
)
if
(
muxer
->
my_
sink_caps
)
gst_caps_unref
(
sink_caps
);
gst_caps_unref
(
muxer
->
my_
sink_caps
);
if
(
muxer
->
container
)
if
(
muxer
->
container
)
{
gst_element_set_state
(
muxer
->
container
,
GST_STATE_NULL
);
gst_object_unref
(
muxer
->
container
);
gst_object_unref
(
muxer
->
container
);
}
free
(
muxer
);
free
(
muxer
);
return
status
;
return
status
;
...
@@ -168,6 +215,7 @@ NTSTATUS wg_muxer_destroy(void *args)
...
@@ -168,6 +215,7 @@ NTSTATUS wg_muxer_destroy(void *args)
stream_free
(
stream
);
stream_free
(
stream
);
}
}
gst_object_unref
(
muxer
->
my_sink
);
gst_object_unref
(
muxer
->
my_sink
);
gst_caps_unref
(
muxer
->
my_sink_caps
);
gst_element_set_state
(
muxer
->
container
,
GST_STATE_NULL
);
gst_element_set_state
(
muxer
->
container
,
GST_STATE_NULL
);
gst_object_unref
(
muxer
->
container
);
gst_object_unref
(
muxer
->
container
);
free
(
muxer
);
free
(
muxer
);
...
@@ -184,7 +232,7 @@ NTSTATUS wg_muxer_add_stream(void *args)
...
@@ -184,7 +232,7 @@ NTSTATUS wg_muxer_add_stream(void *args)
struct
wg_muxer_stream
*
stream
;
struct
wg_muxer_stream
*
stream
;
char
src_pad_name
[
64
];
char
src_pad_name
[
64
];
GST_DEBUG
(
"muxer %p, stream
_id
%u, format %p."
,
muxer
,
params
->
stream_id
,
params
->
format
);
GST_DEBUG
(
"muxer %p, stream %u, format %p."
,
muxer
,
params
->
stream_id
,
params
->
format
);
/* Create stream object. */
/* Create stream object. */
if
(
!
(
stream
=
calloc
(
1
,
sizeof
(
*
stream
))))
if
(
!
(
stream
=
calloc
(
1
,
sizeof
(
*
stream
))))
...
@@ -241,3 +289,57 @@ out:
...
@@ -241,3 +289,57 @@ out:
return
status
;
return
status
;
}
}
NTSTATUS
wg_muxer_start
(
void
*
args
)
{
struct
wg_muxer
*
muxer
=
get_muxer
(
*
(
wg_muxer_t
*
)
args
);
NTSTATUS
status
=
STATUS_UNSUCCESSFUL
;
struct
wg_muxer_stream
*
stream
;
GST_DEBUG
(
"muxer %p."
,
muxer
);
/* Create muxer element. */
if
(
!
(
muxer
->
muxer
=
muxer_find_muxer
(
muxer
))
||
!
gst_bin_add
(
GST_BIN
(
muxer
->
container
),
muxer
->
muxer
))
return
status
;
/* Link muxer element to my_sink */
if
(
!
link_element_to_sink
(
muxer
->
muxer
,
muxer
->
my_sink
)
||
!
gst_pad_set_active
(
muxer
->
my_sink
,
1
))
return
status
;
/* Link each stream to muxer element. */
LIST_FOR_EACH_ENTRY
(
stream
,
&
muxer
->
streams
,
struct
wg_muxer_stream
,
entry
)
{
bool
link_ok
=
stream
->
parser
?
gst_element_link
(
stream
->
parser
,
muxer
->
muxer
)
:
link_src_to_element
(
stream
->
my_src
,
muxer
->
muxer
);
if
(
!
link_ok
)
return
status
;
}
/* Set to pause state. */
if
(
gst_element_set_state
(
muxer
->
container
,
GST_STATE_PAUSED
)
==
GST_STATE_CHANGE_FAILURE
||
gst_element_get_state
(
muxer
->
container
,
NULL
,
NULL
,
-
1
)
==
GST_STATE_CHANGE_FAILURE
)
return
status
;
/* Active stream my_src pad and push events to prepare for streaming. */
LIST_FOR_EACH_ENTRY
(
stream
,
&
muxer
->
streams
,
struct
wg_muxer_stream
,
entry
)
{
char
buffer
[
64
];
sprintf
(
buffer
,
"wg_muxer_stream_src_%u"
,
stream
->
id
);
gst_segment_init
(
&
stream
->
segment
,
GST_FORMAT_BYTES
);
if
(
!
gst_pad_set_active
(
stream
->
my_src
,
1
))
return
status
;
if
(
!
push_event
(
stream
->
my_src
,
gst_event_new_stream_start
(
buffer
))
||
!
push_event
(
stream
->
my_src
,
gst_event_new_caps
(
stream
->
my_src_caps
))
||
!
push_event
(
stream
->
my_src
,
gst_event_new_segment
(
&
stream
->
segment
)))
return
status
;
}
GST_DEBUG
(
"Started muxer %p."
,
muxer
);
return
STATUS_SUCCESS
;
}
dlls/winegstreamer/wg_parser.c
View file @
7cee5e55
...
@@ -1922,6 +1922,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
...
@@ -1922,6 +1922,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
X
(
wg_muxer_create
),
X
(
wg_muxer_create
),
X
(
wg_muxer_destroy
),
X
(
wg_muxer_destroy
),
X
(
wg_muxer_add_stream
),
X
(
wg_muxer_add_stream
),
X
(
wg_muxer_start
),
};
};
C_ASSERT
(
ARRAYSIZE
(
__wine_unix_call_funcs
)
==
unix_wg_funcs_count
);
C_ASSERT
(
ARRAYSIZE
(
__wine_unix_call_funcs
)
==
unix_wg_funcs_count
);
...
@@ -2209,6 +2210,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
...
@@ -2209,6 +2210,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
X64
(
wg_muxer_create
),
X64
(
wg_muxer_create
),
X
(
wg_muxer_destroy
),
X
(
wg_muxer_destroy
),
X64
(
wg_muxer_add_stream
),
X64
(
wg_muxer_add_stream
),
X
(
wg_muxer_start
),
};
};
C_ASSERT
(
ARRAYSIZE
(
__wine_unix_call_wow64_funcs
)
==
unix_wg_funcs_count
);
C_ASSERT
(
ARRAYSIZE
(
__wine_unix_call_wow64_funcs
)
==
unix_wg_funcs_count
);
...
...
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