mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 18:37:17 +00:00
winegstreamer: Introduce new wg_muxer struct.
This commit is contained in:
parent
f413e9ab7d
commit
0915f5f216
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ¶ms)))
|
||||
{
|
||||
*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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
123
dlls/winegstreamer/wg_muxer.c
Normal file
123
dlls/winegstreamer/wg_muxer.c
Normal 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;
|
||||
}
|
|
@ -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(¶ms);
|
||||
}
|
||||
|
||||
|
||||
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(¶ms);
|
||||
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 */
|
||||
|
|
Loading…
Reference in a new issue