mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Updated mfplat-streaming-support patchset
This commit is contained in:
parent
143e59bfe2
commit
6d67766abd
@ -0,0 +1,54 @@
|
||||
From 91f9b02553371a085fed75b86f8a9bcac6cfe36a Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 30 Nov 2020 11:56:48 -0500
|
||||
Subject: [PATCH] mf: Add invalid connect method test.
|
||||
|
||||
Nikolay stripped out this test in his updated version of the patchset, which is fine. But I think it's useful to have it somewhere.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mf/tests/mf.c | 28 ++++++++++++++++++++++++++++
|
||||
1 file changed, 28 insertions(+)
|
||||
|
||||
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
|
||||
index 8272064466f..32ae84b837b 100644
|
||||
--- a/dlls/mf/tests/mf.c
|
||||
+++ b/dlls/mf/tests/mf.c
|
||||
@@ -1824,6 +1824,34 @@ static void test_topology_loader(void)
|
||||
LOADER_TODO,
|
||||
},
|
||||
|
||||
+ {
|
||||
+ /* MP3 -> PCM */
|
||||
+ &MFMediaType_Audio,
|
||||
+ {
|
||||
+ {
|
||||
+ { &MF_MT_SUBTYPE, WAVE_FORMAT_MPEGLAYER3 },
|
||||
+ { &MF_MT_AUDIO_NUM_CHANNELS, 2 },
|
||||
+ { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
|
||||
+ { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000 },
|
||||
+ { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ {
|
||||
+ { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
|
||||
+ { &MF_MT_AUDIO_NUM_CHANNELS, 1 },
|
||||
+ { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
|
||||
+ { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 },
|
||||
+ { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
|
||||
+ { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
|
||||
+ }
|
||||
+ },
|
||||
+
|
||||
+ MF_CONNECT_ALLOW_DECODER &~ MF_CONNECT_ALLOW_CONVERTER,
|
||||
+ MF_E_INVALIDMEDIATYPE,
|
||||
+ LOADER_TODO,
|
||||
+ },
|
||||
+
|
||||
{
|
||||
/* MP3 -> PCM */
|
||||
&MFMediaType_Audio,
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,71 @@
|
||||
From a82543fe671fb36f8179ba2b67b321323ea79375 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 2 Dec 2020 17:12:22 -0500
|
||||
Subject: [PATCH] Allow for compressed types.
|
||||
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 28 ++++++++++++++++++----------
|
||||
1 file changed, 18 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 3a63c9ddc99..2ef734f3a22 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -778,22 +778,20 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
{
|
||||
DWORD rate = -1, channels = -1, channel_mask = -1;
|
||||
|
||||
- if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate)))
|
||||
- {
|
||||
- ERR("Sample rate not set.\n");
|
||||
- return NULL;
|
||||
- }
|
||||
- if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels)))
|
||||
- {
|
||||
- ERR("Channel count not set.\n");
|
||||
- return NULL;
|
||||
- }
|
||||
+ IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate);
|
||||
+ IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels);
|
||||
IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, &channel_mask);
|
||||
|
||||
if (IsEqualGUID(&subtype, &MFAudioFormat_Float))
|
||||
{
|
||||
GstAudioInfo float_info;
|
||||
|
||||
+ if (rate == -1 || channels == -1)
|
||||
+ {
|
||||
+ ERR("Incomplete media type.\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
gst_audio_info_set_format(&float_info, GST_AUDIO_FORMAT_F32LE, rate, channels, NULL);
|
||||
output = gst_audio_info_to_caps(&float_info);
|
||||
}
|
||||
@@ -803,6 +801,12 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
GstAudioInfo pcm_info;
|
||||
DWORD bits_per_sample;
|
||||
|
||||
+ if (rate == -1 || channels == -1)
|
||||
+ {
|
||||
+ ERR("Incomplete media type.\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &bits_per_sample)))
|
||||
{
|
||||
pcm_format = gst_audio_format_build_integer(bits_per_sample > 8, G_LITTLE_ENDIAN, bits_per_sample, bits_per_sample);
|
||||
@@ -822,6 +826,10 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ if (rate != -1)
|
||||
+ gst_caps_set_simple(output, "rate", G_TYPE_INT, rate, NULL);
|
||||
+ if (channels != -1)
|
||||
+ gst_caps_set_simple(output, "channels", G_TYPE_INT, channels, NULL);
|
||||
if (channel_mask != -1)
|
||||
gst_caps_set_simple(output, "channel-mask", GST_TYPE_BITMASK, (guint64) channel_mask, NULL);
|
||||
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,32 @@
|
||||
From 4e4c5c8e491ab06bd4aa981b0efc2c318110e92e Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 14 Oct 2020 11:07:05 -0500
|
||||
Subject: [PATCH] mf/session: Unconditionally deliver NULL (EOS) samples.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mf/session.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/session.c b/dlls/mf/session.c
|
||||
index 1a7439a13c3..07e29cd013f 100644
|
||||
--- a/dlls/mf/session.c
|
||||
+++ b/dlls/mf/session.c
|
||||
@@ -2858,11 +2858,12 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop
|
||||
LIST_FOR_EACH_ENTRY_SAFE(sample_entry, sample_entry2, &topo_node->u.transform.outputs[i].samples,
|
||||
struct sample, entry)
|
||||
{
|
||||
- if (!topo_node->u.transform.outputs[i].requests)
|
||||
+ if (!topo_node->u.transform.outputs[i].requests && sample_entry->sample)
|
||||
break;
|
||||
|
||||
session_deliver_sample_to_node(session, downstream_node, downstream_input, sample_entry->sample);
|
||||
- topo_node->u.transform.outputs[i].requests--;
|
||||
+ if (sample_entry->sample)
|
||||
+ topo_node->u.transform.outputs[i].requests--;
|
||||
|
||||
transform_release_sample(sample_entry);
|
||||
}
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,42 @@
|
||||
From 81b91d516ba31c8ceb9b9025fe265b9b9b5f1a86 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 2 Apr 2020 15:42:18 -0500
|
||||
Subject: [PATCH] mf/session: Request more samples when a transform needs them.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mf/session.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/mf/session.c b/dlls/mf/session.c
|
||||
index 07e29cd013f..5a08a2eb6c6 100644
|
||||
--- a/dlls/mf/session.c
|
||||
+++ b/dlls/mf/session.c
|
||||
@@ -2759,6 +2759,8 @@ static HRESULT transform_node_pull_samples(const struct media_session *session,
|
||||
return hr;
|
||||
}
|
||||
|
||||
+static HRESULT session_request_sample_from_node(struct media_session *session, IMFTopologyNode *node, DWORD output);
|
||||
+
|
||||
static void session_deliver_sample_to_node(struct media_session *session, IMFTopologyNode *node, unsigned int input,
|
||||
IMFSample *sample)
|
||||
{
|
||||
@@ -2834,7 +2836,14 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop
|
||||
WARN("Drain command failed for transform, hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
- transform_node_pull_samples(session, topo_node);
|
||||
+ if (transform_node_pull_samples(session, topo_node) == MF_E_TRANSFORM_NEED_MORE_INPUT && !drain)
|
||||
+ {
|
||||
+ IMFTopologyNode *upstream_node;
|
||||
+ DWORD upstream_output;
|
||||
+
|
||||
+ if (SUCCEEDED(IMFTopologyNode_GetInput(node, input, &upstream_node, &upstream_output)))
|
||||
+ session_request_sample_from_node(session, upstream_node, upstream_output);
|
||||
+ }
|
||||
|
||||
/* Remaining unprocessed input has been discarded, now queue markers for every output. */
|
||||
if (drain)
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,27 @@
|
||||
From c137abfb05cdde838628eef7ca2a4b4dddaf34fb Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 15 Oct 2020 12:18:10 -0500
|
||||
Subject: [PATCH] HACK: Flush decoder when changing times.
|
||||
|
||||
---
|
||||
dlls/mf/session.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/dlls/mf/session.c b/dlls/mf/session.c
|
||||
index 5a08a2eb6c6..a6bc7803390 100644
|
||||
--- a/dlls/mf/session.c
|
||||
+++ b/dlls/mf/session.c
|
||||
@@ -2326,7 +2326,10 @@ static void session_set_presentation_clock(struct media_session *session)
|
||||
LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry)
|
||||
{
|
||||
if (node->type == MF_TOPOLOGY_TRANSFORM_NODE)
|
||||
+ {
|
||||
+ IMFTransform_ProcessMessage(node->object.transform, MFT_MESSAGE_COMMAND_FLUSH, 0);
|
||||
IMFTransform_ProcessMessage(node->object.transform, MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (!(session->presentation.flags & SESSION_FLAG_PRESENTATION_CLOCK_SET))
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,163 @@
|
||||
From 2fdf1938b9506e75398655c37bff6daaa3c567e1 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 2 Nov 2020 09:56:54 -0600
|
||||
Subject: [PATCH] winegstreamer: Add IMFSeekInfo::GetNearestKeyFrames stub.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/media_source.c | 111 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 111 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index dc15ec8d5ca..90c8da42b74 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -92,6 +92,8 @@ struct source_async_command
|
||||
struct media_source
|
||||
{
|
||||
IMFMediaSource IMFMediaSource_iface;
|
||||
+ IMFGetService IMFGetService_iface;
|
||||
+ IMFSeekInfo IMFSeekInfo_iface;
|
||||
IMFAsyncCallback async_commands_callback;
|
||||
LONG ref;
|
||||
DWORD async_commands_queue;
|
||||
@@ -124,6 +126,16 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac
|
||||
return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface);
|
||||
}
|
||||
|
||||
+static inline struct media_source *impl_from_IMFGetService(IMFGetService *iface)
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, struct media_source, IMFGetService_iface);
|
||||
+}
|
||||
+
|
||||
+static inline struct media_source *impl_from_IMFSeekInfo(IMFSeekInfo *iface)
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, struct media_source, IMFSeekInfo_iface);
|
||||
+}
|
||||
+
|
||||
static inline struct media_source *impl_from_async_commands_callback_IMFAsyncCallback(IMFAsyncCallback *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct media_source, async_commands_callback);
|
||||
@@ -978,6 +990,10 @@ static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID
|
||||
{
|
||||
*out = &source->IMFMediaSource_iface;
|
||||
}
|
||||
+ else if(IsEqualIID(riid, &IID_IMFGetService))
|
||||
+ {
|
||||
+ *out = &source->IMFGetService_iface;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("(%s, %p)\n", debugstr_guid(riid), out);
|
||||
@@ -1212,6 +1228,99 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl =
|
||||
media_source_Shutdown,
|
||||
};
|
||||
|
||||
+static HRESULT WINAPI source_get_service_QueryInterface(IMFGetService *iface, REFIID riid, void **obj)
|
||||
+{
|
||||
+ struct media_source *source = impl_from_IMFGetService(iface);
|
||||
+ return IMFMediaSource_QueryInterface(&source->IMFMediaSource_iface, riid, obj);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI source_get_service_AddRef(IMFGetService *iface)
|
||||
+{
|
||||
+ struct media_source *source = impl_from_IMFGetService(iface);
|
||||
+ return IMFMediaSource_AddRef(&source->IMFMediaSource_iface);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI source_get_service_Release(IMFGetService *iface)
|
||||
+{
|
||||
+ struct media_source *source = impl_from_IMFGetService(iface);
|
||||
+ return IMFMediaSource_Release(&source->IMFMediaSource_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI source_get_service_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj)
|
||||
+{
|
||||
+ struct media_source *source = impl_from_IMFGetService(iface);
|
||||
+
|
||||
+ TRACE("(%p)->(%s, %s, %p)\n", source, debugstr_guid(service), debugstr_guid(riid), obj);
|
||||
+
|
||||
+ if (source->state == SOURCE_SHUTDOWN)
|
||||
+ return MF_E_SHUTDOWN;
|
||||
+
|
||||
+ *obj = NULL;
|
||||
+
|
||||
+ if (IsEqualIID(service, &MF_SCRUBBING_SERVICE))
|
||||
+ {
|
||||
+ if (IsEqualIID(riid, &IID_IMFSeekInfo))
|
||||
+ {
|
||||
+ *obj = &source->IMFSeekInfo_iface;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (*obj)
|
||||
+ IUnknown_AddRef((IUnknown*) *obj);
|
||||
+
|
||||
+ return *obj ? S_OK : E_NOINTERFACE;
|
||||
+}
|
||||
+
|
||||
+static const IMFGetServiceVtbl IMFGetService_vtbl =
|
||||
+{
|
||||
+ source_get_service_QueryInterface,
|
||||
+ source_get_service_AddRef,
|
||||
+ source_get_service_Release,
|
||||
+ source_get_service_GetService,
|
||||
+};
|
||||
+
|
||||
+static HRESULT WINAPI source_seek_info_QueryInterface(IMFSeekInfo *iface, REFIID riid, void **obj)
|
||||
+{
|
||||
+ struct media_source *source = impl_from_IMFSeekInfo(iface);
|
||||
+ return IMFMediaSource_QueryInterface(&source->IMFMediaSource_iface, riid, obj);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI source_seek_info_AddRef(IMFSeekInfo *iface)
|
||||
+{
|
||||
+ struct media_source *source = impl_from_IMFSeekInfo(iface);
|
||||
+ return IMFMediaSource_AddRef(&source->IMFMediaSource_iface);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI source_seek_info_Release(IMFSeekInfo *iface)
|
||||
+{
|
||||
+ struct media_source *source = impl_from_IMFSeekInfo(iface);
|
||||
+ return IMFMediaSource_Release(&source->IMFMediaSource_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI source_seek_info_GetNearestKeyFrames(IMFSeekInfo *iface, const GUID *format,
|
||||
+ const PROPVARIANT *position, PROPVARIANT *prev_frame, PROPVARIANT *next_frame)
|
||||
+{
|
||||
+ struct media_source *source = impl_from_IMFSeekInfo(iface);
|
||||
+
|
||||
+ FIXME("(%p)->(%s, %p, %p, %p) - semi-stub\n", source, debugstr_guid(format), position, prev_frame, next_frame);
|
||||
+
|
||||
+ if (source->state == SOURCE_SHUTDOWN)
|
||||
+ return MF_E_SHUTDOWN;
|
||||
+
|
||||
+ PropVariantCopy(prev_frame, position);
|
||||
+ PropVariantCopy(next_frame, position);
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static const IMFSeekInfoVtbl IMFSeekInfo_vtbl =
|
||||
+{
|
||||
+ source_seek_info_QueryInterface,
|
||||
+ source_seek_info_AddRef,
|
||||
+ source_seek_info_Release,
|
||||
+ source_seek_info_GetNearestKeyFrames,
|
||||
+};
|
||||
+
|
||||
static void stream_added(GstElement *element, GstPad *pad, gpointer user)
|
||||
{
|
||||
struct media_source *source = user;
|
||||
@@ -1284,6 +1393,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl;
|
||||
+ object->IMFGetService_iface.lpVtbl = &IMFGetService_vtbl;
|
||||
+ object->IMFSeekInfo_iface.lpVtbl = &IMFSeekInfo_vtbl;
|
||||
object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl;
|
||||
object->ref = 1;
|
||||
object->byte_stream = bytestream;
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,122 @@
|
||||
From 8fbe272f3be23baeb7f88d3567f06760aa89c009 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Fri, 6 Nov 2020 10:06:23 -0600
|
||||
Subject: [PATCH] winegstreamer: Fixup raw audio caps to be compatible with
|
||||
IMFMediaType.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/media_source.c | 7 +++-
|
||||
dlls/winegstreamer/mfplat.c | 57 +++++++++++++++++++++++++++++++
|
||||
3 files changed, 64 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index 075e0ce1f0f..dcf76554b6d 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -79,6 +79,7 @@ extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
extern HRESULT mfplat_DllRegisterServer(void) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||
+GstCaps *make_mf_compatible_caps(GstCaps *caps) DECLSPEC_HIDDEN;
|
||||
IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) DECLSPEC_HIDDEN;
|
||||
GstCaps *caps_from_mf_media_type(IMFMediaType *type) DECLSPEC_HIDDEN;
|
||||
IMFSample *mf_sample_from_gst_buffer(GstBuffer *in) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 90c8da42b74..6280c65e920 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -891,15 +891,20 @@ fail:
|
||||
|
||||
static HRESULT media_stream_init_desc(struct media_stream *stream)
|
||||
{
|
||||
- GstCaps *current_caps = gst_pad_get_current_caps(stream->their_src);
|
||||
+ GstCaps *base_caps = gst_pad_get_current_caps(stream->their_src);
|
||||
IMFMediaTypeHandler *type_handler = NULL;
|
||||
IMFMediaType **stream_types = NULL;
|
||||
IMFMediaType *stream_type = NULL;
|
||||
+ GstCaps *current_caps = make_mf_compatible_caps(base_caps);
|
||||
DWORD type_count = 0;
|
||||
const gchar *major_type;
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
|
||||
+ gst_caps_unref(base_caps);
|
||||
+ if (!current_caps)
|
||||
+ return E_FAIL;
|
||||
+
|
||||
major_type = gst_structure_get_name(gst_caps_get_structure(current_caps, 0));
|
||||
|
||||
if (!strcmp(major_type, "video/x-raw"))
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 2ef734f3a22..8ed2c2b3904 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -709,6 +709,63 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
return media_type;
|
||||
}
|
||||
|
||||
+GstCaps *make_mf_compatible_caps(GstCaps *caps)
|
||||
+{
|
||||
+ GstCaps *ret;
|
||||
+ IMFMediaType *media_type;
|
||||
+ GstStructure *structure;
|
||||
+ const char *mime_type;
|
||||
+
|
||||
+ if (gst_caps_get_size(caps) != 1)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* Optimization: Don't copy caps if no transformation is needed */
|
||||
+ if ((media_type = mf_media_type_from_caps(caps)))
|
||||
+ {
|
||||
+ IMFMediaType_Release(media_type);
|
||||
+ return gst_caps_ref(caps);
|
||||
+ }
|
||||
+
|
||||
+ ret = gst_caps_copy(caps);
|
||||
+ structure = gst_caps_get_structure(ret, 0);
|
||||
+ mime_type = gst_structure_get_name(structure);
|
||||
+
|
||||
+ if (!strcmp(mime_type, "audio/x-raw"))
|
||||
+ {
|
||||
+ const char *format;
|
||||
+ if ((format = gst_structure_get_string(structure, "format")))
|
||||
+ {
|
||||
+ char type;
|
||||
+ unsigned int bits_per_sample;
|
||||
+ char endian[2];
|
||||
+ char new_format[6];
|
||||
+
|
||||
+ if (strlen(format) <= 5 && (sscanf(format, "%c%u%2c", &type, &bits_per_sample, endian) >= 2))
|
||||
+ {
|
||||
+ if (type == 'U' || type == 'S')
|
||||
+ type = bits_per_sample == 8 ? 'U' : 'S';
|
||||
+
|
||||
+ if (endian[0] == 'B')
|
||||
+ endian[0] = 'L';
|
||||
+
|
||||
+ sprintf(new_format, "%c%u%.2s", type, bits_per_sample, bits_per_sample > 8 ? endian : 0);
|
||||
+ gst_caps_set_simple(caps, "format", G_TYPE_STRING, new_format, NULL);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((media_type = mf_media_type_from_caps(ret)))
|
||||
+ IMFMediaType_Release(media_type);
|
||||
+
|
||||
+ if (!media_type)
|
||||
+ {
|
||||
+ gst_caps_unref(ret);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
{
|
||||
GUID major_type;
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,45 @@
|
||||
From fad4f3d78ead1b3a30a53fd1a4074eb0220d2d7f Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 2 Nov 2020 10:18:27 -0600
|
||||
Subject: [PATCH] winegstreamer: Set MF_PD_MIME_TYPE on source's presentation
|
||||
descriptor.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/media_source.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 6280c65e920..049b2b94268 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -1378,6 +1378,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
|
||||
BOOL video_selected = FALSE, audio_selected = FALSE;
|
||||
IMFStreamDescriptor **descriptors = NULL;
|
||||
+ IMFAttributes *byte_stream_attributes;
|
||||
struct media_source *object;
|
||||
gint64 total_pres_time = 0;
|
||||
DWORD bytestream_caps;
|
||||
@@ -1566,6 +1567,18 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
if (object->stream_count)
|
||||
IMFPresentationDescriptor_SetUINT64(object->pres_desc, &MF_PD_DURATION, total_pres_time / 100);
|
||||
|
||||
+ if (SUCCEEDED(IMFByteStream_QueryInterface(object->byte_stream, &IID_IMFAttributes, (void **)&byte_stream_attributes)))
|
||||
+ {
|
||||
+ WCHAR *mimeW = NULL;
|
||||
+ DWORD length;
|
||||
+ if (SUCCEEDED(IMFAttributes_GetAllocatedString(byte_stream_attributes, &MF_BYTESTREAM_CONTENT_TYPE, &mimeW, &length)))
|
||||
+ {
|
||||
+ IMFPresentationDescriptor_SetString(object->pres_desc, &MF_PD_MIME_TYPE, mimeW);
|
||||
+ CoTaskMemFree(mimeW);
|
||||
+ }
|
||||
+ IMFAttributes_Release(byte_stream_attributes);
|
||||
+ }
|
||||
+
|
||||
object->state = SOURCE_STOPPED;
|
||||
|
||||
*out_media_source = object;
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,141 @@
|
||||
From 9aa15670f1c848a0f39538d6bb297b069f45ccfc Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 15 Sep 2020 14:25:26 -0500
|
||||
Subject: [PATCH] winegstreamer: Insert parser into pipeline to rectify type
|
||||
differences.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/media_source.c | 95 ++++++++++++++++++++++++++++++-
|
||||
1 file changed, 92 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 049b2b94268..56c3bd5db70 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -791,8 +791,17 @@ static const IMFMediaStreamVtbl media_stream_vtbl =
|
||||
media_stream_RequestSample
|
||||
};
|
||||
|
||||
-/* Setup a chain of elements which should hopefully allow transformations to any IMFMediaType
|
||||
- the user throws at us through gstreamer's caps negotiation. */
|
||||
+/* There are two paths this function can take.
|
||||
+ 1) In the first path, we are acting as a real media source, purely demuxing the input data,
|
||||
+ in whichever format it may be in, and passing it along. However, there can be different ways
|
||||
+ to interpret the same streams. Subtypes in MF usually carry an implicit meaning, so we define
|
||||
+ what caps an IMFMediaType corresponds to in mfplat.c, and insert a parser between decodebin
|
||||
+ and the appsink, which usually can resolve these differences. As an example, MFVideoFormat_H264
|
||||
+ implies stream-format=byte-stream, and inserting h264parse can transform stream-format=avc
|
||||
+ into stream-format=byte-stream.
|
||||
+ 2) In the second path, we are dealing with x-raw output from decodebin. In this case, we just
|
||||
+ have to setup a chain of elements which should hopefully allow transformations to any IMFMediaType
|
||||
+ the user throws at us through gstreamer's caps negotiation.*/
|
||||
static HRESULT media_stream_connect_to_sink(struct media_stream *stream)
|
||||
{
|
||||
GstCaps *source_caps = gst_pad_query_caps(stream->their_src, NULL);
|
||||
@@ -832,7 +841,68 @@ static HRESULT media_stream_connect_to_sink(struct media_stream *stream)
|
||||
}
|
||||
else
|
||||
{
|
||||
- stream->my_sink = gst_element_get_static_pad(stream->appsink, "sink");
|
||||
+ GstElement *parser = NULL;
|
||||
+ GstCaps *target_caps;
|
||||
+
|
||||
+ assert(gst_caps_is_fixed(source_caps));
|
||||
+
|
||||
+ if (!(target_caps = make_mf_compatible_caps(source_caps)))
|
||||
+ {
|
||||
+ gst_caps_unref(source_caps);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ g_object_set(stream->appsink, "caps", target_caps, NULL);
|
||||
+
|
||||
+ if (!(gst_caps_is_equal(source_caps, target_caps)))
|
||||
+ {
|
||||
+ GList *parser_list_one, *parser_list_two;
|
||||
+ GstElementFactory *parser_factory;
|
||||
+
|
||||
+ parser_list_one = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_PARSER, 1);
|
||||
+
|
||||
+ parser_list_two = gst_element_factory_list_filter(parser_list_one, source_caps, GST_PAD_SINK, 0);
|
||||
+ gst_plugin_feature_list_free(parser_list_one);
|
||||
+ parser_list_one = parser_list_two;
|
||||
+
|
||||
+ parser_list_two = gst_element_factory_list_filter(parser_list_one, target_caps, GST_PAD_SRC, 0);
|
||||
+ gst_plugin_feature_list_free(parser_list_one);
|
||||
+ parser_list_one = parser_list_two;
|
||||
+ gst_caps_unref(target_caps);
|
||||
+
|
||||
+ if (!(g_list_length(parser_list_one)))
|
||||
+ {
|
||||
+ gst_plugin_feature_list_free(parser_list_one);
|
||||
+ ERR("Failed to find parser for stream\n");
|
||||
+ gst_caps_unref(source_caps);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ parser_factory = g_list_first(parser_list_one)->data;
|
||||
+ TRACE("Found parser %s.\n", GST_ELEMENT_NAME(parser_factory));
|
||||
+
|
||||
+ parser = gst_element_factory_create(parser_factory, NULL);
|
||||
+
|
||||
+ gst_plugin_feature_list_free(parser_list_one);
|
||||
+
|
||||
+ if (!parser)
|
||||
+ {
|
||||
+ gst_caps_unref(source_caps);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ gst_bin_add(GST_BIN(stream->parent_source->container), parser);
|
||||
+
|
||||
+ assert(gst_element_link(parser, stream->appsink));
|
||||
+
|
||||
+ gst_element_sync_state_with_parent(parser);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ gst_caps_unref(target_caps);
|
||||
+ }
|
||||
+
|
||||
+ stream->my_sink = gst_element_get_static_pad(parser ? parser : stream->appsink, "sink");
|
||||
}
|
||||
|
||||
if (gst_pad_link(stream->their_src, stream->my_sink) != GST_PAD_LINK_OK)
|
||||
@@ -1326,6 +1396,23 @@ static const IMFSeekInfoVtbl IMFSeekInfo_vtbl =
|
||||
source_seek_info_GetNearestKeyFrames,
|
||||
};
|
||||
|
||||
+/* If this callback is extended to use any significant win32 APIs, a wrapper function
|
||||
+ should be added */
|
||||
+gboolean stream_found(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer user)
|
||||
+{
|
||||
+ GstCaps *target_caps;
|
||||
+
|
||||
+ /* if the stream can be converted into an MF compatible type, we'll go that route
|
||||
+ otherwise, we'll rely on decodebin for the whole process */
|
||||
+
|
||||
+ if ((target_caps = make_mf_compatible_caps(caps)))
|
||||
+ {
|
||||
+ gst_caps_unref(target_caps);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
static void stream_added(GstElement *element, GstPad *pad, gpointer user)
|
||||
{
|
||||
struct media_source *source = user;
|
||||
@@ -1446,6 +1533,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
|
||||
gst_bin_add(GST_BIN(object->container), object->decodebin);
|
||||
|
||||
+ if(!GetEnvironmentVariableA("MF_DECODE_IN_SOURCE", NULL, 0))
|
||||
+ g_signal_connect(object->decodebin, "autoplug-continue", G_CALLBACK(stream_found), object);
|
||||
g_signal_connect(object->decodebin, "pad-added", G_CALLBACK(mf_src_stream_added_wrapper), object);
|
||||
g_signal_connect(object->decodebin, "pad-removed", G_CALLBACK(mf_src_stream_removed_wrapper), object);
|
||||
g_signal_connect(object->decodebin, "no-more-pads", G_CALLBACK(mf_src_no_more_pads_wrapper), object);
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,113 @@
|
||||
From 300990cae9811de9c4e12396cddb087fe83c45f6 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:00:26 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate H.264 caps to attributes.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 75 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 75 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 8ed2c2b3904..cbe325b2fe8 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "mfapi.h"
|
||||
#include "mfidl.h"
|
||||
#include "wmcodecdsp.h"
|
||||
+#include "codecapi.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/heap.h"
|
||||
@@ -628,6 +629,74 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
}
|
||||
}
|
||||
}
|
||||
+ else if (!(strcmp(mime_type, "video/x-h264")))
|
||||
+ {
|
||||
+ const char *profile, *level;
|
||||
+
|
||||
+ /* validation */
|
||||
+ if (strcmp(gst_structure_get_string(info, "stream-format"), "byte-stream"))
|
||||
+ return NULL;
|
||||
+ if (strcmp(gst_structure_get_string(info, "alignment"), "au"))
|
||||
+ return NULL;
|
||||
+ if (gst_structure_get_value(info, "codec-data"))
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* conversion */
|
||||
+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_H264);
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_COMPRESSED, TRUE);
|
||||
+
|
||||
+ if ((profile = gst_structure_get_string(info, "profile")))
|
||||
+ {
|
||||
+ if (!(strcmp(profile, "main")))
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_Main);
|
||||
+ else if (!(strcmp(profile, "high")))
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_High);
|
||||
+ else if (!(strcmp(profile, "high-4:4:4")))
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_444);
|
||||
+ else
|
||||
+ FIXME("Unrecognized profile %s\n", profile);
|
||||
+ }
|
||||
+ if ((level = gst_structure_get_string(info, "level")))
|
||||
+ {
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ const static struct
|
||||
+ {
|
||||
+ const char *name;
|
||||
+ enum eAVEncH264VLevel val;
|
||||
+ } levels[] =
|
||||
+ {
|
||||
+ {"1", eAVEncH264VLevel1},
|
||||
+ {"1.1", eAVEncH264VLevel1_1},
|
||||
+ {"1.2", eAVEncH264VLevel1_2},
|
||||
+ {"1.3", eAVEncH264VLevel1_3},
|
||||
+ {"2", eAVEncH264VLevel2},
|
||||
+ {"2.1", eAVEncH264VLevel2_1},
|
||||
+ {"2.2", eAVEncH264VLevel2_2},
|
||||
+ {"3", eAVEncH264VLevel3},
|
||||
+ {"3.1", eAVEncH264VLevel3_1},
|
||||
+ {"3.2", eAVEncH264VLevel3_2},
|
||||
+ {"4", eAVEncH264VLevel4},
|
||||
+ {"4.1", eAVEncH264VLevel4_1},
|
||||
+ {"4.2", eAVEncH264VLevel4_2},
|
||||
+ {"5", eAVEncH264VLevel5},
|
||||
+ {"5.1", eAVEncH264VLevel5_1},
|
||||
+ {"5.2", eAVEncH264VLevel5_2},
|
||||
+ };
|
||||
+ for (i = 0 ; i < ARRAY_SIZE(levels); i++)
|
||||
+ {
|
||||
+ if (!(strcmp(level, levels[i].name)))
|
||||
+ {
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_MPEG2_LEVEL, levels[i].val);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (i == ARRAY_SIZE(levels))
|
||||
+ {
|
||||
+ FIXME("Unrecognized level %s", level);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("Unrecognized video format %s\n", mime_type);
|
||||
@@ -753,6 +822,12 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps)
|
||||
}
|
||||
}
|
||||
}
|
||||
+ else if (!strcmp(mime_type, "video/x-h264"))
|
||||
+ {
|
||||
+ gst_caps_set_simple(ret, "stream-format", G_TYPE_STRING, "byte-stream", NULL);
|
||||
+ gst_caps_set_simple(ret, "alignment", G_TYPE_STRING, "au", NULL);
|
||||
+ gst_structure_remove_field(structure, "codec_data");
|
||||
+ }
|
||||
|
||||
if ((media_type = mf_media_type_from_caps(ret)))
|
||||
IMFMediaType_Release(media_type);
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,82 @@
|
||||
From acfee7d0386f8a80a75c3f9b014c3574b317db7d Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:01:20 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate WMV caps to attributes.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 51 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 51 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index cbe325b2fe8..f2ca4bacd2b 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -563,6 +563,24 @@ uncompressed_video_formats[] =
|
||||
{&MFVideoFormat_RGB555, GST_VIDEO_FORMAT_BGR15},
|
||||
};
|
||||
|
||||
+static void codec_data_to_user_data(GstStructure *structure, IMFMediaType *type)
|
||||
+{
|
||||
+ const GValue *codec_data;
|
||||
+
|
||||
+ if ((codec_data = gst_structure_get_value(structure, "codec_data")))
|
||||
+ {
|
||||
+ GstBuffer *codec_data_buffer = gst_value_get_buffer(codec_data);
|
||||
+ if (codec_data_buffer)
|
||||
+ {
|
||||
+ gsize codec_data_size = gst_buffer_get_size(codec_data_buffer);
|
||||
+ gpointer codec_data_raw = heap_alloc(codec_data_size);
|
||||
+ gst_buffer_extract(codec_data_buffer, 0, codec_data_raw, codec_data_size);
|
||||
+ IMFMediaType_SetBlob(type, &MF_MT_USER_DATA, codec_data_raw, codec_data_size);
|
||||
+ heap_free(codec_data_raw);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* returns NULL if doesn't match exactly */
|
||||
IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
{
|
||||
@@ -697,6 +715,39 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
}
|
||||
}
|
||||
}
|
||||
+ else if (!(strcmp(mime_type, "video/x-wmv")))
|
||||
+ {
|
||||
+ gint wmv_version;
|
||||
+ const char *format;
|
||||
+
|
||||
+ if (gst_structure_get_int(info, "wmvversion", &wmv_version))
|
||||
+ {
|
||||
+ switch (wmv_version)
|
||||
+ {
|
||||
+ case 1:
|
||||
+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_WMV1);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_WMV2);
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_WMV3);
|
||||
+ break;
|
||||
+ default:
|
||||
+ FIXME("Unrecognized wmvversion %d\n", wmv_version);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((format = gst_structure_get_string(info, "format")))
|
||||
+ {
|
||||
+ if (!(strcmp(format, "WVC1")))
|
||||
+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_WVC1);
|
||||
+ else
|
||||
+ FIXME("Unrecognized format %s\n", format);
|
||||
+ }
|
||||
+
|
||||
+ codec_data_to_user_data(info, media_type);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("Unrecognized video format %s\n", mime_type);
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,139 @@
|
||||
From 14a38dd02707bb645a1f51b3193996a3c5be6c31 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:02:27 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate AAC caps to attributes.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 108 ++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 108 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index f2ca4bacd2b..7d7ba2de0ea 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -563,6 +563,15 @@ uncompressed_video_formats[] =
|
||||
{&MFVideoFormat_RGB555, GST_VIDEO_FORMAT_BGR15},
|
||||
};
|
||||
|
||||
+struct aac_user_data
|
||||
+{
|
||||
+ WORD payload_type;
|
||||
+ WORD profile_level_indication;
|
||||
+ WORD struct_type;
|
||||
+ WORD reserved;
|
||||
+ /* audio-specific-config is stored here */
|
||||
+};
|
||||
+
|
||||
static void codec_data_to_user_data(GstStructure *structure, IMFMediaType *type)
|
||||
{
|
||||
const GValue *codec_data;
|
||||
@@ -813,6 +822,105 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
|
||||
IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, depth);
|
||||
}
|
||||
+ else if (!(strcmp(mime_type, "audio/mpeg")))
|
||||
+ {
|
||||
+ int mpeg_version = -1;
|
||||
+
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_COMPRESSED, TRUE);
|
||||
+
|
||||
+ if (!(gst_structure_get_int(info, "mpegversion", &mpeg_version)))
|
||||
+ ERR("Failed to get mpegversion\n");
|
||||
+ switch (mpeg_version)
|
||||
+ {
|
||||
+ case 2:
|
||||
+ case 4:
|
||||
+ {
|
||||
+ const char *format, *profile, *level;
|
||||
+ DWORD profile_level_indication = 0;
|
||||
+ const GValue *codec_data;
|
||||
+ DWORD asc_size = 0;
|
||||
+ struct aac_user_data *user_data = NULL;
|
||||
+
|
||||
+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_AAC);
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
|
||||
+
|
||||
+ codec_data = gst_structure_get_value(info, "codec_data");
|
||||
+ if (codec_data)
|
||||
+ {
|
||||
+ GstBuffer *codec_data_buffer = gst_value_get_buffer(codec_data);
|
||||
+ if (codec_data_buffer)
|
||||
+ {
|
||||
+ if ((asc_size = gst_buffer_get_size(codec_data_buffer)) >= 2)
|
||||
+ {
|
||||
+ user_data = heap_alloc_zero(sizeof(*user_data)+asc_size);
|
||||
+ gst_buffer_extract(codec_data_buffer, 0, (gpointer)(user_data + 1), asc_size);
|
||||
+ }
|
||||
+ else
|
||||
+ ERR("Unexpected buffer size\n");
|
||||
+ }
|
||||
+ else
|
||||
+ ERR("codec_data not a buffer\n");
|
||||
+ }
|
||||
+ else
|
||||
+ ERR("codec_data not found\n");
|
||||
+ if (!user_data)
|
||||
+ user_data = heap_alloc_zero(sizeof(*user_data));
|
||||
+
|
||||
+ if ((format = gst_structure_get_string(info, "stream-format")))
|
||||
+ {
|
||||
+ DWORD payload_type = -1;
|
||||
+ if (!(strcmp(format, "raw")))
|
||||
+ payload_type = 0;
|
||||
+ else if (!(strcmp(format, "adts")))
|
||||
+ payload_type = 1;
|
||||
+ else if (!(strcmp(format, "adif")))
|
||||
+ payload_type = 2;
|
||||
+ else if (!(strcmp(format, "loas")))
|
||||
+ payload_type = 3;
|
||||
+ else
|
||||
+ FIXME("Unrecognized stream-format\n");
|
||||
+ if (payload_type != -1)
|
||||
+ {
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_AAC_PAYLOAD_TYPE, payload_type);
|
||||
+ user_data->payload_type = payload_type;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ERR("Stream format not present\n");
|
||||
+ }
|
||||
+
|
||||
+ profile = gst_structure_get_string(info, "profile");
|
||||
+ level = gst_structure_get_string(info, "level");
|
||||
+ /* Data from http://archive.is/whp6P#45% */
|
||||
+ if (profile && level)
|
||||
+ {
|
||||
+ if (!(strcmp(profile, "lc")) && !(strcmp(level, "2")))
|
||||
+ profile_level_indication = 0x29;
|
||||
+ else if (!(strcmp(profile, "lc")) && !(strcmp(level, "4")))
|
||||
+ profile_level_indication = 0x2A;
|
||||
+ else if (!(strcmp(profile, "lc")) && !(strcmp(level, "5")))
|
||||
+ profile_level_indication = 0x2B;
|
||||
+ else
|
||||
+ FIXME("Unhandled profile/level combo\n");
|
||||
+ }
|
||||
+ else
|
||||
+ ERR("Profile or level not present\n");
|
||||
+
|
||||
+ if (profile_level_indication)
|
||||
+ {
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, profile_level_indication);
|
||||
+ user_data->profile_level_indication = profile_level_indication;
|
||||
+ }
|
||||
+
|
||||
+ IMFMediaType_SetBlob(media_type, &MF_MT_USER_DATA, (BYTE *)user_data, sizeof(*user_data) + asc_size);
|
||||
+ heap_free(user_data);
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ FIXME("Unhandled mpegversion %d\n", mpeg_version);
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("Unrecognized audio format %s\n", mime_type);
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 25678c8b28cc379a20b1658187625ef88481ead3 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 25 Mar 2020 13:36:19 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate MPEG-4 Section-2 caps to attributes.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 7d7ba2de0ea..8ab679e3a5f 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -757,6 +757,22 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
|
||||
codec_data_to_user_data(info, media_type);
|
||||
}
|
||||
+ else if (!(strcmp(mime_type, "video/mpeg")))
|
||||
+ {
|
||||
+ gint mpegversion;
|
||||
+ if (gst_structure_get_int(info, "mpegversion", &mpegversion))
|
||||
+ {
|
||||
+ if (mpegversion == 4)
|
||||
+ {
|
||||
+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_M4S2);
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_COMPRESSED, TRUE);
|
||||
+
|
||||
+ codec_data_to_user_data(info, media_type);
|
||||
+ }
|
||||
+ else
|
||||
+ FIXME("Unrecognized mpeg version %d\n", mpegversion);
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("Unrecognized video format %s\n", mime_type);
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,48 @@
|
||||
From 5d9a2efb3462978ad2e5373f1e9d8e7abad1de00 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 12 May 2020 17:05:41 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate WMA caps to attributes.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 24 ++++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 8ab679e3a5f..8cc56873d76 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -937,6 +937,30 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
FIXME("Unhandled mpegversion %d\n", mpeg_version);
|
||||
}
|
||||
}
|
||||
+ else if (!(strcmp(mime_type, "audio/x-wma")))
|
||||
+ {
|
||||
+ gint wma_version, block_align;
|
||||
+
|
||||
+ if (gst_structure_get_int(info, "wmaversion", &wma_version))
|
||||
+ {
|
||||
+ switch (wma_version)
|
||||
+ {
|
||||
+ case 2:
|
||||
+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_WMAudioV8);
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_WMAudioV9);
|
||||
+ break;
|
||||
+ default:
|
||||
+ FIXME("Unrecognized wmaversion %d\n", wma_version);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (gst_structure_get_int(info, "block_align", &block_align))
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, block_align);
|
||||
+
|
||||
+ codec_data_to_user_data(info, media_type);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("Unrecognized audio format %s\n", mime_type);
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,128 @@
|
||||
From 5d1c441c46fbc3da1fae8a1761079ec609c765b5 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:18:40 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate H.264 attributes to caps.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 90 +++++++++++++++++++++++++++++--------
|
||||
1 file changed, 71 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 8cc56873d76..f097410da56 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1055,10 +1055,6 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
{
|
||||
UINT64 frame_rate = 0, frame_size = 0;
|
||||
DWORD width, height;
|
||||
- GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
- GUID subtype_base;
|
||||
- GstVideoInfo info;
|
||||
- unsigned int i;
|
||||
|
||||
if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
|
||||
return NULL;
|
||||
@@ -1067,28 +1063,84 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
|
||||
output = gst_caps_new_empty_simple("video/x-raw");
|
||||
|
||||
- for (i = 0; i < ARRAY_SIZE(uncompressed_video_formats); i++)
|
||||
+ if (IsEqualGUID(&subtype, &MFVideoFormat_H264))
|
||||
{
|
||||
- if (IsEqualGUID(uncompressed_video_formats[i].subtype, &subtype))
|
||||
+ enum eAVEncH264VProfile h264_profile;
|
||||
+ enum eAVEncH264VLevel h264_level;
|
||||
+ output = gst_caps_new_empty_simple("video/x-h264");
|
||||
+ gst_caps_set_simple(output, "stream-format", G_TYPE_STRING, "byte-stream", NULL);
|
||||
+ gst_caps_set_simple(output, "alignment", G_TYPE_STRING, "au", NULL);
|
||||
+
|
||||
+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_PROFILE, &h264_profile)))
|
||||
+ {
|
||||
+ const char *profile = NULL;
|
||||
+ switch (h264_profile)
|
||||
+ {
|
||||
+ case eAVEncH264VProfile_Main: profile = "main"; break;
|
||||
+ case eAVEncH264VProfile_High: profile = "high"; break;
|
||||
+ case eAVEncH264VProfile_444: profile = "high-4:4:4"; break;
|
||||
+ default: FIXME("Unknown profile %u\n", h264_profile);
|
||||
+ }
|
||||
+ if (profile)
|
||||
+ gst_caps_set_simple(output, "profile", G_TYPE_STRING, profile, NULL);
|
||||
+ }
|
||||
+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_LEVEL, &h264_level)))
|
||||
{
|
||||
- format = uncompressed_video_formats[i].format;
|
||||
- break;
|
||||
+ const char *level = NULL;
|
||||
+ switch (h264_level)
|
||||
+ {
|
||||
+ case eAVEncH264VLevel1: level = "1"; break;
|
||||
+ case eAVEncH264VLevel1_1: level = "1.1"; break;
|
||||
+ case eAVEncH264VLevel1_2: level = "1.2"; break;
|
||||
+ case eAVEncH264VLevel1_3: level = "1.3"; break;
|
||||
+ case eAVEncH264VLevel2: level = "2"; break;
|
||||
+ case eAVEncH264VLevel2_1: level = "2.1"; break;
|
||||
+ case eAVEncH264VLevel2_2: level = "2.2"; break;
|
||||
+ case eAVEncH264VLevel3: level = "3"; break;
|
||||
+ case eAVEncH264VLevel3_1: level = "3.1"; break;
|
||||
+ case eAVEncH264VLevel3_2: level = "3.2"; break;
|
||||
+ case eAVEncH264VLevel4: level = "4"; break;
|
||||
+ case eAVEncH264VLevel4_1: level = "4.1"; break;
|
||||
+ case eAVEncH264VLevel4_2: level = "4.2"; break;
|
||||
+ case eAVEncH264VLevel5: level = "5"; break;
|
||||
+ case eAVEncH264VLevel5_1: level = "5.1"; break;
|
||||
+ case eAVEncH264VLevel5_2: level = "5.2"; break;
|
||||
+ default: FIXME("Unknown level %u\n", h264_level);
|
||||
+ }
|
||||
+ if (level)
|
||||
+ gst_caps_set_simple(output, "level", G_TYPE_STRING, level, NULL);
|
||||
}
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
+ GUID subtype_base;
|
||||
+ GstVideoInfo info;
|
||||
+ unsigned int i;
|
||||
|
||||
- subtype_base = subtype;
|
||||
- subtype_base.Data1 = 0;
|
||||
- if (format == GST_VIDEO_FORMAT_UNKNOWN && IsEqualGUID(&MFVideoFormat_Base, &subtype_base))
|
||||
- format = gst_video_format_from_fourcc(subtype.Data1);
|
||||
+ for (i = 0; i < ARRAY_SIZE(uncompressed_video_formats); i++)
|
||||
+ {
|
||||
+ if (IsEqualGUID(uncompressed_video_formats[i].subtype, &subtype))
|
||||
+ {
|
||||
+ format = uncompressed_video_formats[i].format;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
||||
- {
|
||||
- FIXME("Unrecognized format %s\n", debugstr_guid(&subtype));
|
||||
- return NULL;
|
||||
- }
|
||||
+ subtype_base = subtype;
|
||||
+ subtype_base.Data1 = 0;
|
||||
+ if (format == GST_VIDEO_FORMAT_UNKNOWN && IsEqualGUID(&MFVideoFormat_Base, &subtype_base))
|
||||
+ format = gst_video_format_from_fourcc(subtype.Data1);
|
||||
|
||||
- gst_video_info_set_format(&info, format, width, height);
|
||||
- output = gst_video_info_to_caps(&info);
|
||||
+ if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
||||
+ {
|
||||
+ FIXME("Unrecognized format %s\n", debugstr_guid(&subtype));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ gst_video_info_set_format(&info, format, width, height);
|
||||
+ output = gst_video_info_to_caps(&info);
|
||||
+ }
|
||||
|
||||
if (frame_size)
|
||||
{
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,82 @@
|
||||
From 47768feab1338d4e2fdcf7a1475630cdbcce5058 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:20:17 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate WMV attributes to caps.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 51 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 51 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index f097410da56..7ec0fd0efe5 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1040,6 +1040,21 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static void user_data_to_codec_data(IMFMediaType *type, GstCaps *caps)
|
||||
+{
|
||||
+ BYTE *user_data;
|
||||
+ DWORD user_data_size;
|
||||
+
|
||||
+ if (SUCCEEDED(IMFMediaType_GetAllocatedBlob(type, &MF_MT_USER_DATA, &user_data, &user_data_size)))
|
||||
+ {
|
||||
+ GstBuffer *codec_data_buffer = gst_buffer_new_allocate(NULL, user_data_size, NULL);
|
||||
+ gst_buffer_fill(codec_data_buffer, 0, user_data, user_data_size);
|
||||
+ gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, codec_data_buffer, NULL);
|
||||
+ gst_buffer_unref(codec_data_buffer);
|
||||
+ CoTaskMemFree(user_data);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
{
|
||||
GUID major_type;
|
||||
@@ -1111,6 +1126,42 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
gst_caps_set_simple(output, "level", G_TYPE_STRING, level, NULL);
|
||||
}
|
||||
}
|
||||
+ else if (IsEqualGUID(&subtype, &MFVideoFormat_WMV1))
|
||||
+ {
|
||||
+ output = gst_caps_new_empty_simple("video/x-wmv");
|
||||
+ gst_caps_set_simple(output, "format", G_TYPE_STRING, "WMV1", NULL);
|
||||
+
|
||||
+ gst_caps_set_simple(output, "wmvversion", G_TYPE_INT, 1, NULL);
|
||||
+
|
||||
+ user_data_to_codec_data(type, output);
|
||||
+ }
|
||||
+ else if (IsEqualGUID(&subtype, &MFVideoFormat_WMV2))
|
||||
+ {
|
||||
+ output = gst_caps_new_empty_simple("video/x-wmv");
|
||||
+ gst_caps_set_simple(output, "format", G_TYPE_STRING, "WMV2", NULL);
|
||||
+
|
||||
+ gst_caps_set_simple(output, "wmvversion", G_TYPE_INT, 2, NULL);
|
||||
+
|
||||
+ user_data_to_codec_data(type, output);
|
||||
+ }
|
||||
+ else if (IsEqualGUID(&subtype, &MFVideoFormat_WMV3))
|
||||
+ {
|
||||
+ output = gst_caps_new_empty_simple("video/x-wmv");
|
||||
+ gst_caps_set_simple(output, "format", G_TYPE_STRING, "WMV3", NULL);
|
||||
+
|
||||
+ gst_caps_set_simple(output, "wmvversion", G_TYPE_INT, 3, NULL);
|
||||
+
|
||||
+ user_data_to_codec_data(type, output);
|
||||
+ }
|
||||
+ else if (IsEqualGUID(&subtype, &MFVideoFormat_WVC1))
|
||||
+ {
|
||||
+ output = gst_caps_new_empty_simple("video/x-wmv");
|
||||
+ gst_caps_set_simple(output, "format", G_TYPE_STRING, "WVC1", NULL);
|
||||
+
|
||||
+ gst_caps_set_simple(output, "wmvversion", G_TYPE_INT, 3, NULL);
|
||||
+
|
||||
+ user_data_to_codec_data(type, output);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,90 @@
|
||||
From b8d81ca669224e964d4f30a90e47c8bd78add56e Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 21 Apr 2020 10:31:02 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate AAC attributes to caps.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 66 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 66 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 7ec0fd0efe5..87cbc3c00c3 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1254,6 +1254,72 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
+ else if (IsEqualGUID(&subtype, &MFAudioFormat_AAC))
|
||||
+ {
|
||||
+ DWORD payload_type, indication;
|
||||
+ struct aac_user_data *user_data;
|
||||
+ UINT32 user_data_size;
|
||||
+ output = gst_caps_new_empty_simple("audio/mpeg");
|
||||
+
|
||||
+ /* Unsure of how to differentiate between mpegversion 2 and 4 */
|
||||
+ gst_caps_set_simple(output, "mpegversion", G_TYPE_INT, 4, NULL);
|
||||
+
|
||||
+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AAC_PAYLOAD_TYPE, &payload_type)))
|
||||
+ {
|
||||
+ switch (payload_type)
|
||||
+ {
|
||||
+ case 0:
|
||||
+ gst_caps_set_simple(output, "stream-format", G_TYPE_STRING, "raw", NULL);
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ gst_caps_set_simple(output, "stream-format", G_TYPE_STRING, "adts", NULL);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ gst_caps_set_simple(output, "stream-format", G_TYPE_STRING, "adif", NULL);
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ gst_caps_set_simple(output, "stream-format", G_TYPE_STRING, "loas", NULL);
|
||||
+ break;
|
||||
+ default:
|
||||
+ gst_caps_set_simple(output, "stream-format", G_TYPE_STRING, "raw", NULL);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ gst_caps_set_simple(output, "stream-format", G_TYPE_STRING, "raw", NULL);
|
||||
+
|
||||
+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, &indication)))
|
||||
+ {
|
||||
+ const char *profile, *level;
|
||||
+ switch (indication)
|
||||
+ {
|
||||
+ case 0x29: profile = "lc"; level = "2"; break;
|
||||
+ case 0x2A: profile = "lc"; level = "4"; break;
|
||||
+ case 0x2B: profile = "lc"; level = "5"; break;
|
||||
+ default:
|
||||
+ {
|
||||
+ profile = level = NULL;
|
||||
+ FIXME("Unrecognized profile-level-indication %u\n", indication);
|
||||
+ }
|
||||
+ }
|
||||
+ if (profile)
|
||||
+ gst_caps_set_simple(output, "profile", G_TYPE_STRING, profile, NULL);
|
||||
+ if (level)
|
||||
+ gst_caps_set_simple(output, "level", G_TYPE_STRING, level, NULL);
|
||||
+ }
|
||||
+
|
||||
+ if (SUCCEEDED(IMFMediaType_GetAllocatedBlob(type, &MF_MT_USER_DATA, (BYTE **) &user_data, &user_data_size)))
|
||||
+ {
|
||||
+ if (user_data_size > sizeof(*user_data))
|
||||
+ {
|
||||
+ GstBuffer *audio_specific_config = gst_buffer_new_allocate(NULL, user_data_size - sizeof(*user_data), NULL);
|
||||
+ gst_buffer_fill(audio_specific_config, 0, user_data + 1, user_data_size - sizeof(*user_data));
|
||||
+
|
||||
+ gst_caps_set_simple(output, "codec_data", GST_TYPE_BUFFER, audio_specific_config, NULL);
|
||||
+ gst_buffer_unref(audio_specific_config);
|
||||
+ }
|
||||
+ CoTaskMemFree(user_data);
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("Unrecognized subtype %s\n", debugstr_guid(&subtype));
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,32 @@
|
||||
From 7b94202165407e1a8cdfc59621e587729e8159d7 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 11 May 2020 16:03:09 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate MPEG-4 Section-2 attributes to caps.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 87cbc3c00c3..53e4cea62e1 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1162,6 +1162,14 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
|
||||
user_data_to_codec_data(type, output);
|
||||
}
|
||||
+ else if (IsEqualGUID(&subtype, &MFVideoFormat_M4S2))
|
||||
+ {
|
||||
+ output = gst_caps_new_empty_simple("video/mpeg");
|
||||
+ gst_caps_set_simple(output, "mpegversion", G_TYPE_INT, 4, NULL);
|
||||
+ gst_caps_set_simple(output, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
|
||||
+
|
||||
+ user_data_to_codec_data(type, output);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,39 @@
|
||||
From e373eef1aad407148299aeac9f53353196059575 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 12 May 2020 17:05:59 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate WMA attributes to caps.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 53e4cea62e1..0d3648048c4 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1328,6 +1328,21 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
CoTaskMemFree(user_data);
|
||||
}
|
||||
}
|
||||
+ else if (IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV9) ||
|
||||
+ IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV8))
|
||||
+ {
|
||||
+ DWORD block_align;
|
||||
+
|
||||
+ output = gst_caps_new_empty_simple("audio/x-wma");
|
||||
+
|
||||
+ gst_caps_set_simple(output, "wmaversion", G_TYPE_INT,
|
||||
+ IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV9) ? 3 : 2, NULL);
|
||||
+
|
||||
+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_align)))
|
||||
+ gst_caps_set_simple(output, "block_align", G_TYPE_INT, block_align, NULL);
|
||||
+
|
||||
+ user_data_to_codec_data(type, output);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("Unrecognized subtype %s\n", debugstr_guid(&subtype));
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,167 @@
|
||||
From d2336422a16efc1ab8572a8638552226d20798f7 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 29 Jan 2020 15:37:39 -0600
|
||||
Subject: [PATCH] tools: Add support for multiple parent directories.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
tools/make_makefiles | 45 +++++++++++++++++++++++++++-----------------
|
||||
tools/makedep.c | 26 +++++++++++++++++--------
|
||||
2 files changed, 46 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/tools/make_makefiles b/tools/make_makefiles
|
||||
index 2d3c14cb2ec..cb4a808244d 100755
|
||||
--- a/tools/make_makefiles
|
||||
+++ b/tools/make_makefiles
|
||||
@@ -229,14 +229,14 @@ sub parse_makefile($)
|
||||
{
|
||||
die "Configure substitution is not allowed in $file" unless $file eq "Makefile";
|
||||
}
|
||||
- if (/^\s*(MODULE|IMPORTLIB|TESTDLL|PARENTSRC|APPMODE|EXTRADLLFLAGS)\s*=\s*(.*)/)
|
||||
+ if (/^\s*(MODULE|IMPORTLIB|TESTDLL|APPMODE|EXTRADLLFLAGS)\s*=\s*(.*)/)
|
||||
{
|
||||
my $var = $1;
|
||||
$make{$var} = $2;
|
||||
next;
|
||||
}
|
||||
my $source_vars_regexp = join "|", @source_vars;
|
||||
- if (/^\s*($source_vars_regexp|PROGRAMS|EXTRA_TARGETS|EXTRA_OBJS|INSTALL_LIB|INSTALL_DEV)\s*=\s*(.*)/)
|
||||
+ if (/^\s*($source_vars_regexp|PROGRAMS|EXTRA_TARGETS|EXTRA_OBJS|INSTALL_LIB|INSTALL_DEV|PARENTSRC)\s*=\s*(.*)/)
|
||||
{
|
||||
my $var = $1;
|
||||
my @list = split(/\s+/, $2);
|
||||
@@ -291,19 +291,27 @@ sub get_makedep_flags($)
|
||||
return %flags;
|
||||
}
|
||||
|
||||
-sub get_parent_makefile($)
|
||||
+sub get_parent_makefiles($)
|
||||
{
|
||||
my $file = shift;
|
||||
my %make = %{$makefiles{$file}};
|
||||
- my $reldir = $make{"PARENTSRC"} || "";
|
||||
- return "" unless $reldir;
|
||||
- (my $path = $file) =~ s/\/Makefile$/\//;
|
||||
- while ($reldir =~ /^\.\.\//)
|
||||
+ my $pointer = $make{"PARENTSRC"} || ();
|
||||
+ return () unless $pointer;
|
||||
+ my @reldirs = @{$pointer};
|
||||
+ my @makefiles = ();
|
||||
+ foreach my $reldir (@reldirs)
|
||||
{
|
||||
- $reldir =~ s/^\.\.\///;
|
||||
- $path =~ s/[^\/]+\/$//;
|
||||
+ my $length = @reldirs;
|
||||
+ (my $path = $file) =~ s/\/Makefile$/\//;
|
||||
+ while ($reldir =~ /^\.\.\//)
|
||||
+ {
|
||||
+ $reldir =~ s/^\.\.\///;
|
||||
+ $path =~ s/[^\/]+\/$//;
|
||||
+ }
|
||||
+ push @makefiles, "$path$reldir/Makefile";
|
||||
}
|
||||
- return "$path$reldir/Makefile";
|
||||
+
|
||||
+ return @makefiles
|
||||
}
|
||||
|
||||
# preserve shared source files that are listed in the existing makefile
|
||||
@@ -404,13 +412,16 @@ sub assign_sources_to_makefiles(@)
|
||||
foreach my $file (@makefiles)
|
||||
{
|
||||
my $make = $makefiles{$file};
|
||||
- my $parent = get_parent_makefile( $file );
|
||||
- next unless $parent;
|
||||
- preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "C_SRCS" );
|
||||
- preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "RC_SRCS" );
|
||||
- preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "IDL_SRCS" );
|
||||
- preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "LEX_SRCS" );
|
||||
- preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "BISON_SRCS" );
|
||||
+ my @parents = get_parent_makefiles( $file );
|
||||
+ next unless @parents;
|
||||
+ foreach my $parent (@parents)
|
||||
+ {
|
||||
+ preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "C_SRCS" );
|
||||
+ preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "RC_SRCS" );
|
||||
+ preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "IDL_SRCS" );
|
||||
+ preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "LEX_SRCS" );
|
||||
+ preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "BISON_SRCS" );
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/tools/makedep.c b/tools/makedep.c
|
||||
index b21362c6c9e..f0d611f1381 100644
|
||||
--- a/tools/makedep.c
|
||||
+++ b/tools/makedep.c
|
||||
@@ -190,11 +190,11 @@ struct makefile
|
||||
struct strarray install_dev;
|
||||
struct strarray extra_targets;
|
||||
struct strarray extra_imports;
|
||||
+ struct strarray parent_dirs;
|
||||
struct list sources;
|
||||
struct list includes;
|
||||
const char *src_dir;
|
||||
const char *obj_dir;
|
||||
- const char *parent_dir;
|
||||
const char *module;
|
||||
const char *testdll;
|
||||
const char *sharedlib;
|
||||
@@ -1388,14 +1388,21 @@ static struct file *open_local_file( const struct makefile *make, const char *pa
|
||||
{
|
||||
char *src_path = src_dir_path( make, path );
|
||||
struct file *ret = load_file( src_path );
|
||||
+ unsigned int i;
|
||||
|
||||
- /* if not found, try parent dir */
|
||||
- if (!ret && make->parent_dir)
|
||||
+ /* if not found, try parent dirs */
|
||||
+ for (i = 0; !ret && i < make->parent_dirs.count; i++)
|
||||
{
|
||||
+ char *new_path;
|
||||
+
|
||||
free( src_path );
|
||||
- path = strmake( "%s/%s", make->parent_dir, path );
|
||||
- src_path = src_dir_path( make, path );
|
||||
+ new_path = strmake( "%s/%s", make->parent_dirs.str[i], path );
|
||||
+ src_path = src_dir_path( make, new_path );
|
||||
ret = load_file( src_path );
|
||||
+ if (ret)
|
||||
+ path = new_path;
|
||||
+ else
|
||||
+ free(new_path);
|
||||
}
|
||||
|
||||
if (ret) *filename = src_path;
|
||||
@@ -4155,13 +4162,13 @@ static void load_sources( struct makefile *make )
|
||||
strarray_set_value( &make->vars, "top_srcdir", root_src_dir_path( "" ));
|
||||
strarray_set_value( &make->vars, "srcdir", src_dir_path( make, "" ));
|
||||
|
||||
- make->parent_dir = get_expanded_make_variable( make, "PARENTSRC" );
|
||||
make->module = get_expanded_make_variable( make, "MODULE" );
|
||||
make->testdll = get_expanded_make_variable( make, "TESTDLL" );
|
||||
make->sharedlib = get_expanded_make_variable( make, "SHAREDLIB" );
|
||||
make->staticlib = get_expanded_make_variable( make, "STATICLIB" );
|
||||
make->importlib = get_expanded_make_variable( make, "IMPORTLIB" );
|
||||
|
||||
+ make->parent_dirs = get_expanded_make_var_array( make, "PARENTSRC" );
|
||||
make->programs = get_expanded_make_var_array( make, "PROGRAMS" );
|
||||
make->scripts = get_expanded_make_var_array( make, "SCRIPTS" );
|
||||
make->imports = get_expanded_make_var_array( make, "IMPORTS" );
|
||||
@@ -4206,8 +4213,11 @@ static void load_sources( struct makefile *make )
|
||||
strarray_add( &make->include_args, strmake( "-I%s", obj_dir_path( make, "" )));
|
||||
if (make->src_dir)
|
||||
strarray_add( &make->include_args, strmake( "-I%s", make->src_dir ));
|
||||
- if (make->parent_dir)
|
||||
- strarray_add( &make->include_args, strmake( "-I%s", src_dir_path( make, make->parent_dir )));
|
||||
+ if (make->parent_dirs.count)
|
||||
+ {
|
||||
+ for (i = 0; i < make->parent_dirs.count; i++)
|
||||
+ strarray_add( &make->include_args, strmake( "-I%s", src_dir_path( make, make->parent_dirs.str[i] )));
|
||||
+ }
|
||||
strarray_add( &make->include_args, "-Iinclude" );
|
||||
if (root_src_dir) strarray_add( &make->include_args, strmake( "-I%s", root_src_dir_path( "include" )));
|
||||
|
||||
--
|
||||
2.29.2
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user