Commit ca01aece authored by Ziqing Hui's avatar Ziqing Hui Committed by Alexandre Julliard

winegstreamer: Implement wg_muxer_add_stream.

parent 1173a2e0
...@@ -112,6 +112,7 @@ HRESULT wg_transform_flush(wg_transform_t transform); ...@@ -112,6 +112,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);
unsigned int wg_format_get_max_size(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) ...@@ -486,6 +486,27 @@ void wg_muxer_destroy(wg_muxer_t muxer)
WINE_UNIX_CALL(unix_wg_muxer_destroy, &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)) #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)
......
...@@ -588,6 +588,7 @@ static HRESULT WINAPI media_sink_AddStreamSink(IMFFinalizableMediaSink *iface, D ...@@ -588,6 +588,7 @@ static HRESULT WINAPI media_sink_AddStreamSink(IMFFinalizableMediaSink *iface, D
{ {
struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(iface); struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(iface);
struct stream_sink *object; struct stream_sink *object;
struct wg_format format;
HRESULT hr; HRESULT hr;
TRACE("iface %p, stream_sink_id %#lx, media_type %p, stream_sink %p.\n", 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 ...@@ -608,6 +609,14 @@ static HRESULT WINAPI media_sink_AddStreamSink(IMFFinalizableMediaSink *iface, D
return hr; 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); list_add_tail(&media_sink->stream_sinks, &object->entry);
LeaveCriticalSection(&media_sink->cs); LeaveCriticalSection(&media_sink->cs);
......
...@@ -67,6 +67,7 @@ extern NTSTATUS wg_transform_flush(void *args) DECLSPEC_HIDDEN; ...@@ -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_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;
/* wg_allocator.c */ /* wg_allocator.c */
......
...@@ -372,6 +372,13 @@ struct wg_muxer_create_params ...@@ -372,6 +372,13 @@ struct wg_muxer_create_params
const char *format; const char *format;
}; };
struct wg_muxer_add_stream_params
{
wg_muxer_t muxer;
UINT32 stream_id;
const struct wg_format *format;
};
enum unix_funcs enum unix_funcs
{ {
unix_wg_init_gstreamer, unix_wg_init_gstreamer,
...@@ -414,6 +421,7 @@ enum unix_funcs ...@@ -414,6 +421,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_funcs_count, unix_wg_funcs_count,
}; };
......
...@@ -22,16 +22,33 @@ ...@@ -22,16 +22,33 @@
#pragma makedep unix #pragma makedep unix
#endif #endif
#include <stdio.h>
#include "ntstatus.h" #include "ntstatus.h"
#define WIN32_NO_STATUS #define WIN32_NO_STATUS
#include "winternl.h" #include "winternl.h"
#include "unix_private.h" #include "unix_private.h"
#include "wine/list.h"
struct wg_muxer struct wg_muxer
{ {
GstElement *container, *muxer; GstElement *container, *muxer;
GstPad *my_sink; 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) 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 ...@@ -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) NTSTATUS wg_muxer_create(void *args)
{ {
struct wg_muxer_create_params *params = args; struct wg_muxer_create_params *params = args;
...@@ -69,6 +93,7 @@ NTSTATUS wg_muxer_create(void *args) ...@@ -69,6 +93,7 @@ NTSTATUS wg_muxer_create(void *args)
/* Create wg_muxer object. */ /* Create wg_muxer object. */
if (!(muxer = calloc(1, sizeof(*muxer)))) if (!(muxer = calloc(1, sizeof(*muxer))))
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
list_init(&muxer->streams);
if (!(muxer->container = gst_bin_new("wg_muxer"))) if (!(muxer->container = gst_bin_new("wg_muxer")))
goto out; goto out;
...@@ -132,7 +157,13 @@ out: ...@@ -132,7 +157,13 @@ out:
NTSTATUS wg_muxer_destroy(void *args) NTSTATUS wg_muxer_destroy(void *args)
{ {
struct wg_muxer *muxer = get_muxer(*(wg_muxer_t *)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_object_unref(muxer->my_sink);
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);
...@@ -140,3 +171,52 @@ NTSTATUS wg_muxer_destroy(void *args) ...@@ -140,3 +171,52 @@ NTSTATUS wg_muxer_destroy(void *args)
return S_OK; 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[] = ...@@ -1945,6 +1945,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),
}; };
C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_wg_funcs_count); C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_wg_funcs_count);
...@@ -2171,6 +2172,23 @@ NTSTATUS wow64_wg_muxer_create(void *args) ...@@ -2171,6 +2172,23 @@ NTSTATUS wow64_wg_muxer_create(void *args)
return ret; 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[] = const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
{ {
#define X64(name) [unix_ ## name] = wow64_ ## name #define X64(name) [unix_ ## name] = wow64_ ## name
...@@ -2214,6 +2232,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = ...@@ -2214,6 +2232,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),
}; };
C_ASSERT(ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_wg_funcs_count); C_ASSERT(ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_wg_funcs_count);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment