mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-21 08:54:09 +00:00
winegstreamer: Implement wg_muxer_add_stream.
This commit is contained in:
parent
1173a2e012
commit
ca01aeced9
|
@ -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);
|
||||
|
||||
|
|
|
@ -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, ¶ms)))
|
||||
{
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(¶ms);
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue