winegstreamer: Introduce new wg_muxer struct.

This commit is contained in:
Ziqing Hui 2023-08-17 09:44:37 +08:00 committed by Alexandre Julliard
parent f413e9ab7d
commit 0915f5f216
8 changed files with 206 additions and 9 deletions

View file

@ -22,6 +22,7 @@ C_SRCS = \
video_processor.c \
wg_allocator.c \
wg_format.c \
wg_muxer.c \
wg_parser.c \
wg_sample.c \
wg_transform.c \

View file

@ -110,6 +110,9 @@ bool wg_transform_get_status(wg_transform_t transform, bool *accepts_input);
HRESULT wg_transform_drain(wg_transform_t transform);
HRESULT wg_transform_flush(wg_transform_t transform);
HRESULT wg_muxer_create(const char *format, wg_muxer_t *muxer);
void wg_muxer_destroy(wg_muxer_t muxer);
unsigned int wg_format_get_max_size(const struct wg_format *format);
HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out);

View file

@ -456,6 +456,32 @@ HRESULT wg_transform_flush(wg_transform_t transform)
return S_OK;
}
HRESULT wg_muxer_create(const char *format, wg_muxer_t *muxer)
{
struct wg_muxer_create_params params =
{
.format = format,
};
NTSTATUS status;
TRACE("format %p, muxer %p.\n", format, muxer);
if (SUCCEEDED(status = WINE_UNIX_CALL(unix_wg_muxer_create, &params)))
{
*muxer = params.muxer;
TRACE("Created wg_muxer %#I64x.\n", params.muxer);
}
return status;
}
void wg_muxer_destroy(wg_muxer_t muxer)
{
TRACE("muxer %#I64x.\n", muxer);
WINE_UNIX_CALL(unix_wg_muxer_destroy, &muxer);
}
#define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1))
unsigned int wg_format_get_stride(const struct wg_format *format)

View file

@ -58,6 +58,11 @@ extern NTSTATUS wg_transform_get_status(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_transform_drain(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_transform_flush(void *args) DECLSPEC_HIDDEN;
/* wg_muxer.c */
extern NTSTATUS wg_muxer_create(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_muxer_destroy(void *args) DECLSPEC_HIDDEN;
/* wg_allocator.c */
static inline BYTE *wg_sample_data(struct wg_sample *sample)

View file

@ -87,15 +87,21 @@ GstElement *find_element(GstElementFactoryListType type, GstCaps *src_caps, GstC
if (!(transforms = gst_element_factory_list_get_elements(type, GST_RANK_MARGINAL)))
goto done;
tmp = gst_element_factory_list_filter(transforms, src_caps, GST_PAD_SINK, FALSE);
gst_plugin_feature_list_free(transforms);
if (!(transforms = tmp))
goto done;
if (src_caps)
{
tmp = gst_element_factory_list_filter(transforms, src_caps, GST_PAD_SINK, FALSE);
gst_plugin_feature_list_free(transforms);
if (!(transforms = tmp))
goto done;
}
tmp = gst_element_factory_list_filter(transforms, sink_caps, GST_PAD_SRC, FALSE);
gst_plugin_feature_list_free(transforms);
if (!(transforms = tmp))
goto done;
if (sink_caps)
{
tmp = gst_element_factory_list_filter(transforms, sink_caps, GST_PAD_SRC, FALSE);
gst_plugin_feature_list_free(transforms);
if (!(transforms = tmp))
goto done;
}
transforms = g_list_sort(transforms, gst_plugin_feature_rank_compare_func);
for (tmp = transforms; tmp != NULL && element == NULL; tmp = tmp->next)

View file

@ -209,6 +209,7 @@ enum wg_parser_type
typedef UINT64 wg_parser_t;
typedef UINT64 wg_parser_stream_t;
typedef UINT64 wg_transform_t;
typedef UINT64 wg_muxer_t;
struct wg_parser_create_params
{
@ -365,6 +366,12 @@ struct wg_transform_get_status_params
UINT32 accepts_input;
};
struct wg_muxer_create_params
{
wg_muxer_t muxer;
const char *format;
};
enum unix_funcs
{
unix_wg_init_gstreamer,
@ -404,6 +411,9 @@ enum unix_funcs
unix_wg_transform_get_status,
unix_wg_transform_drain,
unix_wg_transform_flush,
unix_wg_muxer_create,
unix_wg_muxer_destroy,
};
#endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */

View file

@ -0,0 +1,123 @@
/*
* GStreamer muxer backend
*
* Copyright 2023 Ziqing Hui for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if 0
#pragma makedep unix
#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "winternl.h"
#include "unix_private.h"
struct wg_muxer
{
GstElement *container, *muxer;
GstPad *my_sink;
};
static struct wg_muxer *get_muxer(wg_muxer_t muxer)
{
return (struct wg_muxer *)(ULONG_PTR)muxer;
}
NTSTATUS wg_muxer_create(void *args)
{
struct wg_muxer_create_params *params = args;
GstElement *first = NULL, *last = NULL;
GstPadTemplate *template = NULL;
GstCaps *sink_caps = NULL;
NTSTATUS status = E_FAIL;
struct wg_muxer *muxer;
/* Create wg_muxer object. */
if (!(muxer = calloc(1, sizeof(*muxer))))
return E_OUTOFMEMORY;
if (!(muxer->container = gst_bin_new("wg_muxer")))
goto out;
/* Create sink pad. */
if (!(sink_caps = gst_caps_from_string(params->format)))
{
GST_ERROR("Failed to get caps from format string: \"%s\".", params->format);
goto out;
}
if (!(template = gst_pad_template_new("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)))
goto out;
muxer->my_sink = gst_pad_new_from_template(template, "wg_muxer_sink");
if (!muxer->my_sink)
goto out;
gst_pad_set_element_private(muxer->my_sink, muxer);
/* 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_caps_unref(sink_caps);
GST_INFO("Created winegstreamer muxer %p.", muxer);
params->muxer = (wg_transform_t)(ULONG_PTR)muxer;
return S_OK;
out:
if (muxer->my_sink)
gst_object_unref(muxer->my_sink);
if (template)
gst_object_unref(template);
if (sink_caps)
gst_caps_unref(sink_caps);
if (muxer->container)
{
gst_element_set_state(muxer->container, GST_STATE_NULL);
gst_object_unref(muxer->container);
}
free(muxer);
return status;
}
NTSTATUS wg_muxer_destroy(void *args)
{
struct wg_muxer *muxer = get_muxer(*(wg_muxer_t *)args);
gst_object_unref(muxer->my_sink);
gst_element_set_state(muxer->container, GST_STATE_NULL);
gst_object_unref(muxer->container);
free(muxer);
return S_OK;
}

View file

@ -1945,6 +1945,9 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
X(wg_transform_get_status),
X(wg_transform_drain),
X(wg_transform_flush),
X(wg_muxer_create),
X(wg_muxer_destroy),
};
#ifdef _WIN64
@ -2052,7 +2055,6 @@ static NTSTATUS wow64_wg_parser_stream_copy_buffer(void *args)
return wg_parser_stream_copy_buffer(&params);
}
static NTSTATUS wow64_wg_parser_stream_get_tag(void *args)
{
struct
@ -2152,6 +2154,24 @@ NTSTATUS wow64_wg_transform_read_data(void *args)
return ret;
}
NTSTATUS wow64_wg_muxer_create(void *args)
{
struct
{
wg_muxer_t muxer;
PTR32 format;
} *params32 = args;
struct wg_muxer_create_params params =
{
.format = ULongToPtr(params32->format),
};
NTSTATUS ret;
ret = wg_muxer_create(&params);
params32->muxer = params.muxer;
return ret;
}
const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
{
#define X64(name) [unix_ ## name] = wow64_ ## name
@ -2192,6 +2212,9 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
X(wg_transform_get_status),
X(wg_transform_drain),
X(wg_transform_flush),
X64(wg_muxer_create),
X(wg_muxer_destroy),
};
#endif /* _WIN64 */