winegstreamer: Implement wg_muxer_add_stream.

This commit is contained in:
Ziqing Hui 2023-08-17 10:28:10 +08:00 committed by Alexandre Julliard
parent 1173a2e012
commit ca01aeced9
7 changed files with 139 additions and 0 deletions

View file

@ -112,6 +112,7 @@ 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);
HRESULT wg_muxer_add_stream(wg_muxer_t muxer, UINT32 stream_id, const struct wg_format *format);
unsigned int wg_format_get_max_size(const struct wg_format *format);

View file

@ -486,6 +486,27 @@ void wg_muxer_destroy(wg_muxer_t muxer)
WINE_UNIX_CALL(unix_wg_muxer_destroy, &muxer);
}
HRESULT wg_muxer_add_stream(wg_muxer_t muxer, UINT32 stream_id, const struct wg_format *format)
{
struct wg_muxer_add_stream_params params =
{
.muxer = muxer,
.stream_id = stream_id,
.format = format,
};
NTSTATUS status;
TRACE("muxer %#I64x, stream_id %u, format %p.\n", muxer, stream_id, format);
if ((status = WINE_UNIX_CALL(unix_wg_muxer_add_stream, &params)))
{
WARN("Failed to add stream, status %#lx.\n", status);
return HRESULT_FROM_NT(status);
}
return S_OK;
}
#define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1))
unsigned int wg_format_get_stride(const struct wg_format *format)

View file

@ -588,6 +588,7 @@ static HRESULT WINAPI media_sink_AddStreamSink(IMFFinalizableMediaSink *iface, D
{
struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(iface);
struct stream_sink *object;
struct wg_format format;
HRESULT hr;
TRACE("iface %p, stream_sink_id %#lx, media_type %p, stream_sink %p.\n",
@ -608,6 +609,14 @@ static HRESULT WINAPI media_sink_AddStreamSink(IMFFinalizableMediaSink *iface, D
return hr;
}
mf_media_type_to_wg_format(media_type, &format);
if (FAILED(hr = wg_muxer_add_stream(media_sink->muxer, stream_sink_id, &format)))
{
LeaveCriticalSection(&media_sink->cs);
IMFStreamSink_Release(&object->IMFStreamSink_iface);
return hr;
}
list_add_tail(&media_sink->stream_sinks, &object->entry);
LeaveCriticalSection(&media_sink->cs);

View file

@ -67,6 +67,7 @@ extern NTSTATUS wg_transform_flush(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_add_stream(void *args) DECLSPEC_HIDDEN;
/* wg_allocator.c */

View file

@ -372,6 +372,13 @@ struct wg_muxer_create_params
const char *format;
};
struct wg_muxer_add_stream_params
{
wg_muxer_t muxer;
UINT32 stream_id;
const struct wg_format *format;
};
enum unix_funcs
{
unix_wg_init_gstreamer,
@ -414,6 +421,7 @@ enum unix_funcs
unix_wg_muxer_create,
unix_wg_muxer_destroy,
unix_wg_muxer_add_stream,
unix_wg_funcs_count,
};

View file

@ -22,16 +22,33 @@
#pragma makedep unix
#endif
#include <stdio.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "winternl.h"
#include "unix_private.h"
#include "wine/list.h"
struct wg_muxer
{
GstElement *container, *muxer;
GstPad *my_sink;
struct list streams;
};
struct wg_muxer_stream
{
struct wg_muxer *muxer;
struct wg_format format;
uint32_t id;
GstPad *my_src;
GstCaps *my_src_caps;
struct list entry;
};
static struct wg_muxer *get_muxer(wg_muxer_t muxer)
@ -57,6 +74,13 @@ static gboolean muxer_sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *qu
}
}
static void stream_free(struct wg_muxer_stream *stream)
{
gst_object_unref(stream->my_src);
gst_caps_unref(stream->my_src_caps);
free(stream);
}
NTSTATUS wg_muxer_create(void *args)
{
struct wg_muxer_create_params *params = args;
@ -69,6 +93,7 @@ NTSTATUS wg_muxer_create(void *args)
/* Create wg_muxer object. */
if (!(muxer = calloc(1, sizeof(*muxer))))
return STATUS_NO_MEMORY;
list_init(&muxer->streams);
if (!(muxer->container = gst_bin_new("wg_muxer")))
goto out;
@ -132,7 +157,13 @@ out:
NTSTATUS wg_muxer_destroy(void *args)
{
struct wg_muxer *muxer = get_muxer(*(wg_muxer_t *)args);
struct wg_muxer_stream *stream, *next;
LIST_FOR_EACH_ENTRY_SAFE(stream, next, &muxer->streams, struct wg_muxer_stream, entry)
{
list_remove(&stream->entry);
stream_free(stream);
}
gst_object_unref(muxer->my_sink);
gst_element_set_state(muxer->container, GST_STATE_NULL);
gst_object_unref(muxer->container);
@ -140,3 +171,52 @@ NTSTATUS wg_muxer_destroy(void *args)
return S_OK;
}
NTSTATUS wg_muxer_add_stream(void *args)
{
struct wg_muxer_add_stream_params *params = args;
struct wg_muxer *muxer = get_muxer(params->muxer);
NTSTATUS status = STATUS_UNSUCCESSFUL;
GstPadTemplate *template = NULL;
struct wg_muxer_stream *stream;
char src_pad_name[64];
GST_DEBUG("muxer %p, stream_id %u, format %p.", muxer, params->stream_id, params->format);
/* Create stream object. */
if (!(stream = calloc(1, sizeof(*stream))))
return STATUS_NO_MEMORY;
stream->muxer = muxer;
stream->format = *params->format;
stream->id = params->stream_id;
/* Create stream my_src pad. */
if (!(stream->my_src_caps = wg_format_to_caps(params->format)))
goto out;
if (!(template = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, stream->my_src_caps)))
goto out;
sprintf(src_pad_name, "wg_muxer_stream_src_%u", stream->id);
if (!(stream->my_src = gst_pad_new_from_template(template, src_pad_name)))
goto out;
gst_pad_set_element_private(stream->my_src, stream);
/* Add to muxer stream list. */
list_add_tail(&muxer->streams, &stream->entry);
gst_object_unref(template);
GST_INFO("Created winegstreamer muxer stream %p.", stream);
return STATUS_SUCCESS;
out:
if (stream->my_src)
gst_object_unref(stream->my_src);
if (template)
gst_object_unref(template);
if (stream->my_src_caps)
gst_caps_unref(stream->my_src_caps);
free(stream);
return status;
}

View file

@ -1945,6 +1945,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
X(wg_muxer_create),
X(wg_muxer_destroy),
X(wg_muxer_add_stream),
};
C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_wg_funcs_count);
@ -2171,6 +2172,23 @@ NTSTATUS wow64_wg_muxer_create(void *args)
return ret;
}
NTSTATUS wow64_wg_muxer_add_stream(void *args)
{
struct
{
wg_muxer_t muxer;
UINT32 stream_id;
PTR32 format;
} *params32 = args;
struct wg_muxer_add_stream_params params =
{
.muxer = params32->muxer,
.stream_id = params32->stream_id,
.format = ULongToPtr(params32->format),
};
return wg_muxer_add_stream(&params);
}
const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
{
#define X64(name) [unix_ ## name] = wow64_ ## name
@ -2214,6 +2232,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
X64(wg_muxer_create),
X(wg_muxer_destroy),
X64(wg_muxer_add_stream),
};
C_ASSERT(ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_wg_funcs_count);