Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- include/wmcodecdsp.idl | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/wmcodecdsp.idl b/include/wmcodecdsp.idl index 1e43766a358..809e528d7e2 100644 --- a/include/wmcodecdsp.idl +++ b/include/wmcodecdsp.idl @@ -20,6 +20,7 @@ import "mediaobj.idl"; import "strmif.idl";
cpp_quote("DEFINE_GUID(MEDIASUBTYPE_I420,0x30323449,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);") +cpp_quote("DEFINE_GUID(MEDIASUBTYPE_MSAUDIO1,0x00000160,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);")
[ uuid(bbeea841-0a63-4f52-a7ab-a9b3a84ed38a)
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/mf.c | 238 +++++++++++++++++++-------------------------- 1 file changed, 102 insertions(+), 136 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 0d4cb05711a..80fe2bf9d1e 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -29,6 +29,7 @@
#include "initguid.h" #include "ole2.h" +#include "propvarutil.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); DEFINE_GUID(MFVideoFormat_P208, 0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); @@ -97,6 +98,17 @@ static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID IUnknown_Release(unk); }
+struct attribute_desc +{ + const GUID *key; + const char *name; + PROPVARIANT value; +}; +typedef struct attribute_desc media_type_desc[32]; + +#define ATTR_GUID(k, g) {.key = &k, .name = #k, {.vt = VT_CLSID, .puuid = (GUID *)&g}} +#define ATTR_UINT32(k, v) {.key = &k, .name = #k, {.vt = VT_UI4, .ulVal = v}} + static HWND create_window(void) { RECT r = {0, 0, 640, 480}; @@ -1605,38 +1617,18 @@ static IMFMediaSource *create_test_source(void) return &source->IMFMediaSource_iface; }
-struct type_attr -{ - const GUID *key; - unsigned int value; -}; - -static void init_media_type(IMFMediaType *mediatype, const GUID *major, const struct type_attr *attrs) +static void init_media_type(IMFMediaType *mediatype, const struct attribute_desc *desc, ULONG limit) { HRESULT hr; + ULONG i;
hr = IMFMediaType_DeleteAllItems(mediatype); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, major); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - - while (attrs->key) + for (i = 0; i < limit && desc[i].key; ++i) { - if (IsEqualGUID(attrs->key, &MF_MT_SUBTYPE)) - { - GUID subtype; - - memcpy(&subtype, IsEqualGUID(major, &MFMediaType_Audio) ? &MFAudioFormat_Base : &MFVideoFormat_Base, - sizeof(subtype)); - subtype.Data1 = attrs->value; - hr = IMFMediaType_SetGUID(mediatype, attrs->key, &subtype); - } - else - hr = IMFMediaType_SetUINT32(mediatype, attrs->key, attrs->value); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - - attrs++; + hr = IMFMediaType_SetItem(mediatype, desc[i].key, &desc[i].value); + ok(hr == S_OK, "SetItem %s returned %#x\n", debugstr_a(desc[i].name), hr); } }
@@ -1718,16 +1710,8 @@ static void test_topology_loader(void) { static const struct loader_test { - const GUID *major; - struct - { - struct type_attr attrs[8]; - } input_type; - struct - { - struct type_attr attrs[8]; - } output_type; - + media_type_desc input_type; + media_type_desc output_type; MF_CONNECT_METHOD method; HRESULT expected_result; unsigned int flags; @@ -1736,26 +1720,23 @@ static void test_topology_loader(void) { { /* PCM -> PCM, same type */ - &MFMediaType_Audio, { - { - { &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 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, { - { - { &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 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), },
MF_CONNECT_DIRECT, @@ -1764,26 +1745,23 @@ static void test_topology_loader(void)
{ /* PCM -> PCM, different bps. */ - &MFMediaType_Audio, { - { - { &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 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, { - { - { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM }, - { &MF_MT_AUDIO_NUM_CHANNELS, 1 }, - { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000 }, - { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000 }, - { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, - { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), },
MF_CONNECT_DIRECT, @@ -1792,26 +1770,23 @@ static void test_topology_loader(void)
{ /* PCM -> PCM, different bps. */ - &MFMediaType_Audio, { - { - { &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 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, { - { - { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM }, - { &MF_MT_AUDIO_NUM_CHANNELS, 1 }, - { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000 }, - { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000 }, - { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, - { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), },
MF_CONNECT_ALLOW_CONVERTER, @@ -1821,25 +1796,22 @@ static void test_topology_loader(void)
{ /* 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 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_MP3), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000), + ATTR_UINT32(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 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), },
MF_CONNECT_DIRECT, @@ -1848,25 +1820,22 @@ static void test_topology_loader(void)
{ /* 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 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_MP3), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000), + ATTR_UINT32(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 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), },
MF_CONNECT_ALLOW_CONVERTER, @@ -1876,25 +1845,22 @@ static void test_topology_loader(void)
{ /* 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 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_MP3), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000), + ATTR_UINT32(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 }, - } + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), },
MF_CONNECT_ALLOW_DECODER, @@ -2023,8 +1989,8 @@ todo_wine { const struct loader_test *test = &loader_tests[i];
- init_media_type(input_type, test->major, test->input_type.attrs); - init_media_type(output_type, test->major, test->output_type.attrs); + init_media_type(input_type, test->input_type, -1); + init_media_type(output_type, test->output_type, -1);
hr = MFCreateSampleGrabberSinkActivate(output_type, &test_grabber_callback, &sink_activate); ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr);
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 20/01/22 11:41, Rémi Bernon ha scritto:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/mf/tests/mf.c | 238 +++++++++++++++++++-------------------------- 1 file changed, 102 insertions(+), 136 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 0d4cb05711a..80fe2bf9d1e 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -29,6 +29,7 @@
#include "initguid.h" #include "ole2.h" +#include "propvarutil.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); DEFINE_GUID(MFVideoFormat_P208, 0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); @@ -97,6 +98,17 @@ static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID IUnknown_Release(unk); }
+struct attribute_desc +{
- const GUID *key;
- const char *name;
- PROPVARIANT value;
+}; +typedef struct attribute_desc media_type_desc[32];
+#define ATTR_GUID(k, g) {.key = &k, .name = #k, {.vt = VT_CLSID, .puuid = (GUID *)&g}} +#define ATTR_UINT32(k, v) {.key = &k, .name = #k, {.vt = VT_UI4, .ulVal = v}}
- static HWND create_window(void) { RECT r = {0, 0, 640, 480};
@@ -1605,38 +1617,18 @@ static IMFMediaSource *create_test_source(void) return &source->IMFMediaSource_iface; }
-struct type_attr -{
- const GUID *key;
- unsigned int value;
-};
-static void init_media_type(IMFMediaType *mediatype, const GUID *major, const struct type_attr *attrs) +static void init_media_type(IMFMediaType *mediatype, const struct attribute_desc *desc, ULONG limit) { HRESULT hr;
ULONG i;
hr = IMFMediaType_DeleteAllItems(mediatype); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, major);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- while (attrs->key)
- for (i = 0; i < limit && desc[i].key; ++i) {
if (IsEqualGUID(attrs->key, &MF_MT_SUBTYPE))
{
GUID subtype;
memcpy(&subtype, IsEqualGUID(major, &MFMediaType_Audio) ? &MFAudioFormat_Base : &MFVideoFormat_Base,
sizeof(subtype));
subtype.Data1 = attrs->value;
hr = IMFMediaType_SetGUID(mediatype, attrs->key, &subtype);
}
else
hr = IMFMediaType_SetUINT32(mediatype, attrs->key, attrs->value);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
attrs++;
hr = IMFMediaType_SetItem(mediatype, desc[i].key, &desc[i].value);
}ok(hr == S_OK, "SetItem %s returned %#x\n", debugstr_a(desc[i].name), hr); }
@@ -1718,16 +1710,8 @@ static void test_topology_loader(void) { static const struct loader_test {
const GUID *major;
struct
{
struct type_attr attrs[8];
} input_type;
struct
{
struct type_attr attrs[8];
} output_type;
media_type_desc input_type;
media_type_desc output_type; MF_CONNECT_METHOD method; HRESULT expected_result; unsigned int flags;
@@ -1736,26 +1720,23 @@ static void test_topology_loader(void) { { /* PCM -> PCM, same type */
&MFMediaType_Audio, {
{
{ &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 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1),
ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, {
{
{ &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 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1),
ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, MF_CONNECT_DIRECT,
@@ -1764,26 +1745,23 @@ static void test_topology_loader(void)
{ /* PCM -> PCM, different bps. */
&MFMediaType_Audio, {
{
{ &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 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1),
ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, {
{
{ &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
{ &MF_MT_AUDIO_NUM_CHANNELS, 1 },
{ &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000 },
{ &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000 },
{ &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
{ &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000),
ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1),
ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, MF_CONNECT_DIRECT,
@@ -1792,26 +1770,23 @@ static void test_topology_loader(void)
{ /* PCM -> PCM, different bps. */
&MFMediaType_Audio, {
{
{ &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 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1),
ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, {
{
{ &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
{ &MF_MT_AUDIO_NUM_CHANNELS, 1 },
{ &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000 },
{ &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000 },
{ &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
{ &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000),
ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1),
ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, MF_CONNECT_ALLOW_CONVERTER,
@@ -1821,25 +1796,22 @@ static void test_topology_loader(void)
{ /* 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 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_MP3),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000),
ATTR_UINT32(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 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1),
ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, MF_CONNECT_DIRECT,
@@ -1848,25 +1820,22 @@ static void test_topology_loader(void)
{ /* 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 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_MP3),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000),
ATTR_UINT32(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 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1),
ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, MF_CONNECT_ALLOW_CONVERTER,
@@ -1876,25 +1845,22 @@ static void test_topology_loader(void)
{ /* 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 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_MP3),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000),
ATTR_UINT32(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 },
}
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM),
ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1),
ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100),
ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1),
ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }, MF_CONNECT_ALLOW_DECODER,
@@ -2023,8 +1989,8 @@ todo_wine { const struct loader_test *test = &loader_tests[i];
init_media_type(input_type, test->major, test->input_type.attrs);
init_media_type(output_type, test->major, test->output_type.attrs);
init_media_type(input_type, test->input_type, -1);
init_media_type(output_type, test->output_type, -1); hr = MFCreateSampleGrabberSinkActivate(output_type, &test_grabber_callback, &sink_activate); ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr);
Hi,
Il 20/01/22 11:41, Rémi Bernon ha scritto:
init_media_type(input_type, test->input_type, -1);
init_media_type(output_type, test->output_type, -1);
It seems that init_media_type() is always called with -1. Does it make sense to keep that count argument?
Giovanni.
On 1/21/22 13:31, Giovanni Mascellani wrote:
Hi,
Il 20/01/22 11:41, Rémi Bernon ha scritto:
+ init_media_type(input_type, test->input_type, -1); + init_media_type(output_type, test->output_type, -1);
It seems that init_media_type() is always called with -1. Does it make sense to keep that count argument?
Giovanni.
Yes, it's going to be useful later where I want to partially initialize media types to check the attributes that are required by the transform.
I could add the argument later, but it didn't seem to hurt.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/mf.c | 129 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 80fe2bf9d1e..1ba1bc4691d 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -28,7 +28,9 @@ #include "winbase.h"
#include "initguid.h" +#include "mediaobj.h" #include "ole2.h" +#include "wmcodecdsp.h" #include "propvarutil.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); @@ -5350,6 +5352,132 @@ static void test_MFRequireProtectedEnvironment(void) IMFPresentationDescriptor_Release(pd); }
+static BOOL create_transform(GUID category, MFT_REGISTER_TYPE_INFO *input_type, + MFT_REGISTER_TYPE_INFO *output_type, const WCHAR *expect_name, + const media_type_desc *expect_input, ULONG expect_input_count, + const media_type_desc *expect_output, ULONG expect_output_count, + IMFTransform **transform, GUID *class_id) +{ + MFT_REGISTER_TYPE_INFO *input_types = NULL, *output_types = NULL; + UINT32 input_count = 0, output_count = 0; + GUID *class_ids = NULL; + ULONG count = 0, i; + WCHAR *name; + HRESULT hr; + + hr = MFTEnum(category, 0, input_type, output_type, NULL, &class_ids, &count); + if (FAILED(hr)) + { + todo_wine + win_skip("Failed to enumerate %s, skipping tests.\n", debugstr_w(expect_name)); + return FALSE; + } + + ok(hr == S_OK, "MFTEnum returned %x\n", hr); + ok(count == 1, "got %u\n", count); + *class_id = class_ids[0]; + CoTaskMemFree(class_ids); + + hr = MFTGetInfo(*class_id, &name, &input_types, &input_count, &output_types, &output_count, NULL); + if (FAILED(hr)) + { + todo_wine + win_skip("Failed to get %s info, skipping tests.\n", debugstr_w(expect_name)); + } + else + { + ok(hr == S_OK, "MFTEnum returned %x\n", hr); + ok(!wcscmp(name, expect_name), "got name %s\n", debugstr_w(name)); + ok(input_count == expect_input_count, "got input_count %u\n", input_count); + for (i = 0; i < input_count; ++i) + { + ok(IsEqualGUID(&input_types[i].guidMajorType, expect_input[i][0].value.puuid), + "got input[%u] major %s\n", i, debugstr_guid(&input_types[i].guidMajorType)); + ok(IsEqualGUID(&input_types[i].guidSubtype, expect_input[i][1].value.puuid), + "got input[%u] subtype %s\n", i, debugstr_guid(&input_types[i].guidSubtype)); + } + ok(output_count == expect_output_count, "got output_count %u\n", output_count); + for (i = 0; i < output_count; ++i) + { + ok(IsEqualGUID(&output_types[i].guidMajorType, expect_output[i][0].value.puuid), + "got output[%u] major %s\n", i, debugstr_guid(&output_types[i].guidMajorType)); + ok(IsEqualGUID(&output_types[i].guidSubtype, expect_output[i][1].value.puuid), + "got output[%u] subtype %s\n", i, debugstr_guid(&output_types[i].guidSubtype)); + } + CoTaskMemFree(output_types); + CoTaskMemFree(input_types); + CoTaskMemFree(name); + } + + hr = CoCreateInstance(class_id, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)transform); + if (FAILED(hr)) + { + todo_wine + win_skip("Failed to create %s instance, skipping tests.\n", debugstr_w(expect_name)); + return FALSE; + } + + return TRUE; +} + +static void test_wma_decoder(void) +{ + static const media_type_desc transform_inputs[] = + { + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_MSAUDIO1), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_WMAudioV8), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_WMAudioV9), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_WMAudio_Lossless), + }, + }; + static const media_type_desc transform_outputs[] = + { + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_Float), + }, + }; + + MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Audio, MFAudioFormat_WMAudioV8}; + MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Audio, MFAudioFormat_Float}; + IMFTransform *transform; + GUID class_id; + HRESULT hr; + ULONG ret; + + hr = CoInitialize(NULL); + ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr); + + if (!create_transform(MFT_CATEGORY_AUDIO_DECODER, &input_type, &output_type, L"WMAudio Decoder MFT", + transform_inputs, ARRAY_SIZE(transform_inputs), transform_outputs, ARRAY_SIZE(transform_outputs), + &transform, &class_id)) + goto failed; + + todo_wine + check_interface(transform, &IID_IMediaObject, TRUE); + + ret = IMFTransform_Release(transform); + ok(ret == 0, "Release returned %u\n", ret); + +failed: + CoUninitialize(); +} + START_TEST(mf) { init_functions(); @@ -5383,4 +5511,5 @@ START_TEST(mf) test_sample_copier_output_processing(); test_MFGetTopoNodeCurrentType(); test_MFRequireProtectedEnvironment(); + test_wma_decoder(); }
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 20/01/22 11:41, Rémi Bernon ha scritto:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/mf/tests/mf.c | 129 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 80fe2bf9d1e..1ba1bc4691d 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -28,7 +28,9 @@ #include "winbase.h"
#include "initguid.h" +#include "mediaobj.h" #include "ole2.h" +#include "wmcodecdsp.h" #include "propvarutil.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); @@ -5350,6 +5352,132 @@ static void test_MFRequireProtectedEnvironment(void) IMFPresentationDescriptor_Release(pd); }
+static BOOL create_transform(GUID category, MFT_REGISTER_TYPE_INFO *input_type,
MFT_REGISTER_TYPE_INFO *output_type, const WCHAR *expect_name,
const media_type_desc *expect_input, ULONG expect_input_count,
const media_type_desc *expect_output, ULONG expect_output_count,
IMFTransform **transform, GUID *class_id)
+{
- MFT_REGISTER_TYPE_INFO *input_types = NULL, *output_types = NULL;
- UINT32 input_count = 0, output_count = 0;
- GUID *class_ids = NULL;
- ULONG count = 0, i;
- WCHAR *name;
- HRESULT hr;
- hr = MFTEnum(category, 0, input_type, output_type, NULL, &class_ids, &count);
- if (FAILED(hr))
- {
todo_wine
win_skip("Failed to enumerate %s, skipping tests.\n", debugstr_w(expect_name));
return FALSE;
- }
- ok(hr == S_OK, "MFTEnum returned %x\n", hr);
- ok(count == 1, "got %u\n", count);
- *class_id = class_ids[0];
- CoTaskMemFree(class_ids);
- hr = MFTGetInfo(*class_id, &name, &input_types, &input_count, &output_types, &output_count, NULL);
- if (FAILED(hr))
- {
todo_wine
win_skip("Failed to get %s info, skipping tests.\n", debugstr_w(expect_name));
- }
- else
- {
ok(hr == S_OK, "MFTEnum returned %x\n", hr);
ok(!wcscmp(name, expect_name), "got name %s\n", debugstr_w(name));
ok(input_count == expect_input_count, "got input_count %u\n", input_count);
for (i = 0; i < input_count; ++i)
{
ok(IsEqualGUID(&input_types[i].guidMajorType, expect_input[i][0].value.puuid),
"got input[%u] major %s\n", i, debugstr_guid(&input_types[i].guidMajorType));
ok(IsEqualGUID(&input_types[i].guidSubtype, expect_input[i][1].value.puuid),
"got input[%u] subtype %s\n", i, debugstr_guid(&input_types[i].guidSubtype));
}
ok(output_count == expect_output_count, "got output_count %u\n", output_count);
for (i = 0; i < output_count; ++i)
{
ok(IsEqualGUID(&output_types[i].guidMajorType, expect_output[i][0].value.puuid),
"got output[%u] major %s\n", i, debugstr_guid(&output_types[i].guidMajorType));
ok(IsEqualGUID(&output_types[i].guidSubtype, expect_output[i][1].value.puuid),
"got output[%u] subtype %s\n", i, debugstr_guid(&output_types[i].guidSubtype));
}
CoTaskMemFree(output_types);
CoTaskMemFree(input_types);
CoTaskMemFree(name);
- }
- hr = CoCreateInstance(class_id, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)transform);
- if (FAILED(hr))
- {
todo_wine
win_skip("Failed to create %s instance, skipping tests.\n", debugstr_w(expect_name));
return FALSE;
- }
- return TRUE;
+}
+static void test_wma_decoder(void) +{
- static const media_type_desc transform_inputs[] =
- {
{
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_MSAUDIO1),
},
{
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_WMAudioV8),
},
{
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_WMAudioV9),
},
{
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_WMAudio_Lossless),
},
- };
- static const media_type_desc transform_outputs[] =
- {
{
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM),
},
{
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio),
ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_Float),
},
- };
- MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Audio, MFAudioFormat_WMAudioV8};
- MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Audio, MFAudioFormat_Float};
- IMFTransform *transform;
- GUID class_id;
- HRESULT hr;
- ULONG ret;
- hr = CoInitialize(NULL);
- ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
- if (!create_transform(MFT_CATEGORY_AUDIO_DECODER, &input_type, &output_type, L"WMAudio Decoder MFT",
transform_inputs, ARRAY_SIZE(transform_inputs), transform_outputs, ARRAY_SIZE(transform_outputs),
&transform, &class_id))
goto failed;
- todo_wine
- check_interface(transform, &IID_IMediaObject, TRUE);
- ret = IMFTransform_Release(transform);
- ok(ret == 0, "Release returned %u\n", ret);
+failed:
- CoUninitialize();
+}
- START_TEST(mf) { init_functions();
@@ -5383,4 +5511,5 @@ START_TEST(mf) test_sample_copier_output_processing(); test_MFGetTopoNodeCurrentType(); test_MFRequireProtectedEnvironment();
- test_wma_decoder(); }
Hi,
Il 20/01/22 11:41, Rémi Bernon ha scritto:
- ok(hr == S_OK, "MFTEnum returned %x\n", hr);
- ok(count == 1, "got %u\n", count);
- *class_id = class_ids[0];
- CoTaskMemFree(class_ids);
Would it make sense to check that the returned class id matches indeed CLSID_WMADecMediaObject?
Giovanni.
On 1/21/22 13:33, Giovanni Mascellani wrote:
Hi,
Il 20/01/22 11:41, Rémi Bernon ha scritto:
+ ok(hr == S_OK, "MFTEnum returned %x\n", hr); + ok(count == 1, "got %u\n", count); + *class_id = class_ids[0]; + CoTaskMemFree(class_ids);
Would it make sense to check that the returned class id matches indeed CLSID_WMADecMediaObject?
Giovanni.
I though about it, we could probably, I wasn't completely sure if it was going to be useful.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/Makefile.in | 3 +- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/mfplat.c | 29 +++++++++++++++- dlls/winegstreamer/winegstreamer_classes.idl | 6 ++++ dlls/winegstreamer/wma_decoder.c | 36 ++++++++++++++++++++ 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 dlls/winegstreamer/wma_decoder.c
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in index 76e6aeed54d..7eecfb4655e 100644 --- a/dlls/winegstreamer/Makefile.in +++ b/dlls/winegstreamer/Makefile.in @@ -15,7 +15,8 @@ C_SRCS = \ wg_parser.c \ wm_asyncreader.c \ wm_reader.c \ - wm_syncreader.c + wm_syncreader.c \ + wma_decoder.c
IDL_SRCS = \ winegstreamer_classes.idl diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 9e1d67417d4..72b2db3734e 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -116,6 +116,7 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) DE
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
+HRESULT wma_decoder_create(REFIID riid, void **ret) DECLSPEC_HIDDEN; HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
struct wm_stream diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index 5404728ba83..8d1286328e9 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -21,6 +21,7 @@
#include "ks.h" #include "ksmedia.h" +#include "wmcodecdsp.h" #include "initguid.h" #include "mfapi.h"
@@ -407,6 +408,7 @@ class_objects[] = { &CLSID_VideoProcessorMFT, &video_processor_create }, { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create }, { &CLSID_WINEAudioConverter, &audio_converter_create }, + { &CLSID_WMADecMediaObject, &wma_decoder_create }, };
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) @@ -442,6 +444,20 @@ static const GUID *audio_converter_supported_types[] = &MFAudioFormat_Float, };
+static WCHAR wma_decoderW[] = L"WMAudio Decoder MFT"; +static const GUID *wma_decoder_input_types[] = +{ + &MEDIASUBTYPE_MSAUDIO1, + &MFAudioFormat_WMAudioV8, + &MFAudioFormat_WMAudioV9, + &MFAudioFormat_WMAudio_Lossless, +}; +static const GUID *wma_decoder_output_types[] = +{ + &MFAudioFormat_PCM, + &MFAudioFormat_Float, +}; + static const struct mft { const GUID *clsid; @@ -467,13 +483,24 @@ mfts[] = ARRAY_SIZE(audio_converter_supported_types), audio_converter_supported_types, }, + { + &CLSID_WMADecMediaObject, + &MFT_CATEGORY_AUDIO_DECODER, + wma_decoderW, + MFT_ENUM_FLAG_SYNCMFT, + &MFMediaType_Audio, + ARRAY_SIZE(wma_decoder_input_types), + wma_decoder_input_types, + ARRAY_SIZE(wma_decoder_output_types), + wma_decoder_output_types, + }, };
HRESULT mfplat_DllRegisterServer(void) { unsigned int i, j; HRESULT hr; - MFT_REGISTER_TYPE_INFO input_types[2], output_types[2]; + MFT_REGISTER_TYPE_INFO input_types[4], output_types[2];
for (i = 0; i < ARRAY_SIZE(mfts); i++) { diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl index 072ec90eea4..90dc1dc839b 100644 --- a/dlls/winegstreamer/winegstreamer_classes.idl +++ b/dlls/winegstreamer/winegstreamer_classes.idl @@ -67,3 +67,9 @@ coclass GStreamerByteStreamHandler {} uuid(6a170414-aad9-4693-b806-3a0c47c570d6) ] coclass WINEAudioConverter { } + +[ + threading(both), + uuid(2eeb4adf-4578-4d10-bca7-bb955f56320a) +] +coclass CWMADecMediaObject {}; diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c new file mode 100644 index 00000000000..1280d7b1efb --- /dev/null +++ b/dlls/winegstreamer/wma_decoder.c @@ -0,0 +1,36 @@ +/* WMA Decoder Transform + * + * Copyright 2022 Rémi Bernon 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 + */ + +#include "gst_private.h" + +#include "mfapi.h" +#include "mferror.h" +#include "mfobjects.h" +#include "mftransform.h" + +#include "wine/debug.h" +#include "wine/heap.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mfplat); + +HRESULT wma_decoder_create(REFIID riid, void **ret) +{ + FIXME("riid %s, ret %p stub!\n", debugstr_guid(riid), ret); + return E_NOTIMPL; +}
On 1/20/22 04:41, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/winegstreamer/Makefile.in | 3 +- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/mfplat.c | 29 +++++++++++++++- dlls/winegstreamer/winegstreamer_classes.idl | 6 ++++ dlls/winegstreamer/wma_decoder.c | 36 ++++++++++++++++++++ 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 dlls/winegstreamer/wma_decoder.c
Is there an application that requires this, other than FAudio?
And if not, can we instead try to change FAudio to not require specific decoders?
Hi,
Il 21/01/22 02:44, Zebediah Figura (she/her) ha scritto:
Is there an application that requires this, other than FAudio?
I don't know, but notice that Mono ships a copy of FAudio, so if we want to patch FAudio, we have to patch that one as well.
And if not, can we instead try to change FAudio to not require specific decoders?
Even if the current user is just FAudio, wouldn't it better to implement properly CWMADecMediaObject anyway? This way you automatically catch all future users of it. Why is CWMADecMediaObject something that we might not want to implement?
Giovanni.
On 1/21/22 09:57, Giovanni Mascellani wrote:
Hi,
Il 21/01/22 02:44, Zebediah Figura (she/her) ha scritto:
Is there an application that requires this, other than FAudio?
I don't know, but notice that Mono ships a copy of FAudio, so if we want to patch FAudio, we have to patch that one as well.
Well, I patched FAudio to implement WMA decoding using MF and WMADecMediaObject, so sure, we can make more changes but now I think what's missing is in Wine.
And if not, can we instead try to change FAudio to not require specific decoders?
Even if the current user is just FAudio, wouldn't it better to implement properly CWMADecMediaObject anyway? This way you automatically catch all future users of it. Why is CWMADecMediaObject something that we might not want to implement?
Giovanni.
I don't think we can. XAudio / FAudio are provided raw WMA buffers and expect to be able to decode the buffer more or less synchronously. This is already implemented, and I don't see any reason to look for another way now.
On 1/21/22 02:57, Giovanni Mascellani wrote:
Hi,
Il 21/01/22 02:44, Zebediah Figura (she/her) ha scritto:
Is there an application that requires this, other than FAudio?
I don't know, but notice that Mono ships a copy of FAudio, so if we want to patch FAudio, we have to patch that one as well.
And if not, can we instead try to change FAudio to not require specific decoders?
Even if the current user is just FAudio, wouldn't it better to implement properly CWMADecMediaObject anyway? This way you automatically catch all future users of it. Why is CWMADecMediaObject something that we might not want to implement?
We will need some way to decode arbitrary data via IMFTransform objects, but it seems preferable to avoid having to implement more objects than we need. E.g. trying to catch as many as possible via a generic decoder seems like a good idea. In that case we'd want to use MFTEnum() in FAudio instead of hardcoding the CLSID.
On 1/21/22 18:23, Zebediah Figura (she/her) wrote:
On 1/21/22 02:57, Giovanni Mascellani wrote:
Hi,
Il 21/01/22 02:44, Zebediah Figura (she/her) ha scritto:
Is there an application that requires this, other than FAudio?
I don't know, but notice that Mono ships a copy of FAudio, so if we want to patch FAudio, we have to patch that one as well.
And if not, can we instead try to change FAudio to not require specific decoders?
Even if the current user is just FAudio, wouldn't it better to implement properly CWMADecMediaObject anyway? This way you automatically catch all future users of it. Why is CWMADecMediaObject something that we might not want to implement?
We will need some way to decode arbitrary data via IMFTransform objects, but it seems preferable to avoid having to implement more objects than we need. E.g. trying to catch as many as possible via a generic decoder seems like a good idea. In that case we'd want to use MFTEnum() in FAudio instead of hardcoding the CLSID.
From the few early tests I've made each transform seems to have its own behavior and some games heavily hardcode their logic around it.
I think catching everything behind a generic decoder is not a good idea in that situation, and it makes the code harder to understand as the specific logic that needs to be implement to satisfy each game and each corner case is interleaved together.
I don't really why it would be so bad to keep them split for now until we have a better view of how different they are. If there really is so many of them and if they really are similar, it'd be simpler to refactor things later when we now what we need to cover. But I don't think it's going to be the case.
I think most of the transform code is going to be very simple anyway, and just a matter of validating media types and a bit of sequence logic, the meat of the decoding is delegated to Gstreamer.
Cheers,
On 1/21/22 11:41, Rémi Bernon wrote:
On 1/21/22 18:23, Zebediah Figura (she/her) wrote:
On 1/21/22 02:57, Giovanni Mascellani wrote:
Hi,
Il 21/01/22 02:44, Zebediah Figura (she/her) ha scritto:
Is there an application that requires this, other than FAudio?
I don't know, but notice that Mono ships a copy of FAudio, so if we want to patch FAudio, we have to patch that one as well.
And if not, can we instead try to change FAudio to not require specific decoders?
Even if the current user is just FAudio, wouldn't it better to implement properly CWMADecMediaObject anyway? This way you automatically catch all future users of it. Why is CWMADecMediaObject something that we might not want to implement?
We will need some way to decode arbitrary data via IMFTransform objects, but it seems preferable to avoid having to implement more objects than we need. E.g. trying to catch as many as possible via a generic decoder seems like a good idea. In that case we'd want to use MFTEnum() in FAudio instead of hardcoding the CLSID.
From the few early tests I've made each transform seems to have its own behavior and some games heavily hardcode their logic around it.
I think catching everything behind a generic decoder is not a good idea in that situation, and it makes the code harder to understand as the specific logic that needs to be implement to satisfy each game and each corner case is interleaved together.
I'm not necessarily arguing for keeping *everything* behind a generic decoder, but it'd be nice to catch everything that doesn't otherwise care. Sure, some applications are going to depend on idiosyncratic behaviour, but the hope is that most are more well-behaved and don't care, especially if they're using MFTEnum() rather than hardcoding CLSIDs in the first place.
I don't really why it would be so bad to keep them split for now until we have a better view of how different they are. If there really is so many of them and if they really are similar, it'd be simpler to refactor things later when we now what we need to cover. But I don't think it's going to be the case.
I think most of the transform code is going to be very simple anyway, and just a matter of validating media types and a bit of sequence logic, the meat of the decoding is delegated to Gstreamer.
Simple, sure, but even as stubs it's over 300 lines. Seems like the kind of thing it'd be nice to avoid if possible.
On 1/21/22 19:03, Zebediah Figura (she/her) wrote:
On 1/21/22 11:41, Rémi Bernon wrote:
On 1/21/22 18:23, Zebediah Figura (she/her) wrote:
On 1/21/22 02:57, Giovanni Mascellani wrote:
Hi,
Il 21/01/22 02:44, Zebediah Figura (she/her) ha scritto:
Is there an application that requires this, other than FAudio?
I don't know, but notice that Mono ships a copy of FAudio, so if we want to patch FAudio, we have to patch that one as well.
And if not, can we instead try to change FAudio to not require specific decoders?
Even if the current user is just FAudio, wouldn't it better to implement properly CWMADecMediaObject anyway? This way you automatically catch all future users of it. Why is CWMADecMediaObject something that we might not want to implement?
We will need some way to decode arbitrary data via IMFTransform objects, but it seems preferable to avoid having to implement more objects than we need. E.g. trying to catch as many as possible via a generic decoder seems like a good idea. In that case we'd want to use MFTEnum() in FAudio instead of hardcoding the CLSID.
From the few early tests I've made each transform seems to have its own behavior and some games heavily hardcode their logic around it.
I think catching everything behind a generic decoder is not a good idea in that situation, and it makes the code harder to understand as the specific logic that needs to be implement to satisfy each game and each corner case is interleaved together.
I'm not necessarily arguing for keeping *everything* behind a generic decoder, but it'd be nice to catch everything that doesn't otherwise care. Sure, some applications are going to depend on idiosyncratic behaviour, but the hope is that most are more well-behaved and don't care, especially if they're using MFTEnum() rather than hardcoding CLSIDs in the first place.
All the games I've seen which required the MF transforms (H264 and AAC) are instantiating them by their class id.
FAudio does it too for the WMA decoder, and although it could use MFTEnum I don't see how easier it would make anything else, we'll still need that WMA decoder class, or a class which can decode WMA.
For now it's the only class there is so it's named wma_decoder, but could easily be renamed later if it matches some other codec.
I don't really why it would be so bad to keep them split for now until we have a better view of how different they are. If there really is so many of them and if they really are similar, it'd be simpler to refactor things later when we now what we need to cover. But I don't think it's going to be the case.
I think most of the transform code is going to be very simple anyway, and just a matter of validating media types and a bit of sequence logic, the meat of the decoding is delegated to Gstreamer.
Simple, sure, but even as stubs it's over 300 lines. Seems like the kind of thing it'd be nice to avoid if possible.
The fully working WMA decoder implementation (still has a lot of stubs, but native one has too) is 638 lines. H264 is 702 lines and an early rip-off of WMA for AAC is also ~600 lines, they all share a new common unix-side wg_transform object which is 721 lines. Doesn't really seem too bad to me.
For comparison, "generic" decode transform that's been floating around is 1230 lines, and doesn't work with some of the games I've tried with (and is also broken in 7.0). I don't know how much specific code it needed on the wg_parser side, but there was some.
On 1/21/22 12:19, Rémi Bernon wrote:
On 1/21/22 19:03, Zebediah Figura (she/her) wrote:
On 1/21/22 11:41, Rémi Bernon wrote:
On 1/21/22 18:23, Zebediah Figura (she/her) wrote:
On 1/21/22 02:57, Giovanni Mascellani wrote:
Hi,
Il 21/01/22 02:44, Zebediah Figura (she/her) ha scritto:
Is there an application that requires this, other than FAudio?
I don't know, but notice that Mono ships a copy of FAudio, so if we want to patch FAudio, we have to patch that one as well.
And if not, can we instead try to change FAudio to not require specific decoders?
Even if the current user is just FAudio, wouldn't it better to implement properly CWMADecMediaObject anyway? This way you automatically catch all future users of it. Why is CWMADecMediaObject something that we might not want to implement?
We will need some way to decode arbitrary data via IMFTransform objects, but it seems preferable to avoid having to implement more objects than we need. E.g. trying to catch as many as possible via a generic decoder seems like a good idea. In that case we'd want to use MFTEnum() in FAudio instead of hardcoding the CLSID.
From the few early tests I've made each transform seems to have its own behavior and some games heavily hardcode their logic around it.
I think catching everything behind a generic decoder is not a good idea in that situation, and it makes the code harder to understand as the specific logic that needs to be implement to satisfy each game and each corner case is interleaved together.
I'm not necessarily arguing for keeping *everything* behind a generic decoder, but it'd be nice to catch everything that doesn't otherwise care. Sure, some applications are going to depend on idiosyncratic behaviour, but the hope is that most are more well-behaved and don't care, especially if they're using MFTEnum() rather than hardcoding CLSIDs in the first place.
All the games I've seen which required the MF transforms (H264 and AAC) are instantiating them by their class id.
FAudio does it too for the WMA decoder, and although it could use MFTEnum I don't see how easier it would make anything else, we'll still need that WMA decoder class, or a class which can decode WMA.
For now it's the only class there is so it's named wma_decoder, but could easily be renamed later if it matches some other codec.
Okay, if there's no known application that uses MFTEnum() then I guess there's not much point in creating a generic transform instead of the WMA object.
[Seems like a huge step back from the era of DirectShow. I guess this is what happens when you make APIs much harder to use...]
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 20/01/22 11:41, Rémi Bernon ha scritto:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/winegstreamer/Makefile.in | 3 +- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/mfplat.c | 29 +++++++++++++++- dlls/winegstreamer/winegstreamer_classes.idl | 6 ++++ dlls/winegstreamer/wma_decoder.c | 36 ++++++++++++++++++++ 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 dlls/winegstreamer/wma_decoder.c
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in index 76e6aeed54d..7eecfb4655e 100644 --- a/dlls/winegstreamer/Makefile.in +++ b/dlls/winegstreamer/Makefile.in @@ -15,7 +15,8 @@ C_SRCS = \ wg_parser.c \ wm_asyncreader.c \ wm_reader.c \
- wm_syncreader.c
wm_syncreader.c \
wma_decoder.c
IDL_SRCS = \ winegstreamer_classes.idl
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 9e1d67417d4..72b2db3734e 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -116,6 +116,7 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) DE
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
+HRESULT wma_decoder_create(REFIID riid, void **ret) DECLSPEC_HIDDEN; HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
struct wm_stream diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index 5404728ba83..8d1286328e9 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -21,6 +21,7 @@
#include "ks.h" #include "ksmedia.h" +#include "wmcodecdsp.h" #include "initguid.h" #include "mfapi.h"
@@ -407,6 +408,7 @@ class_objects[] = { &CLSID_VideoProcessorMFT, &video_processor_create }, { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create }, { &CLSID_WINEAudioConverter, &audio_converter_create },
{ &CLSID_WMADecMediaObject, &wma_decoder_create }, };
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
@@ -442,6 +444,20 @@ static const GUID *audio_converter_supported_types[] = &MFAudioFormat_Float, };
+static WCHAR wma_decoderW[] = L"WMAudio Decoder MFT"; +static const GUID *wma_decoder_input_types[] = +{
- &MEDIASUBTYPE_MSAUDIO1,
- &MFAudioFormat_WMAudioV8,
- &MFAudioFormat_WMAudioV9,
- &MFAudioFormat_WMAudio_Lossless,
+}; +static const GUID *wma_decoder_output_types[] = +{
- &MFAudioFormat_PCM,
- &MFAudioFormat_Float,
+};
- static const struct mft { const GUID *clsid;
@@ -467,13 +483,24 @@ mfts[] = ARRAY_SIZE(audio_converter_supported_types), audio_converter_supported_types, },
{
&CLSID_WMADecMediaObject,
&MFT_CATEGORY_AUDIO_DECODER,
wma_decoderW,
MFT_ENUM_FLAG_SYNCMFT,
&MFMediaType_Audio,
ARRAY_SIZE(wma_decoder_input_types),
wma_decoder_input_types,
ARRAY_SIZE(wma_decoder_output_types),
wma_decoder_output_types,
}, };
HRESULT mfplat_DllRegisterServer(void) { unsigned int i, j; HRESULT hr;
- MFT_REGISTER_TYPE_INFO input_types[2], output_types[2];
MFT_REGISTER_TYPE_INFO input_types[4], output_types[2];
for (i = 0; i < ARRAY_SIZE(mfts); i++) {
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl index 072ec90eea4..90dc1dc839b 100644 --- a/dlls/winegstreamer/winegstreamer_classes.idl +++ b/dlls/winegstreamer/winegstreamer_classes.idl @@ -67,3 +67,9 @@ coclass GStreamerByteStreamHandler {} uuid(6a170414-aad9-4693-b806-3a0c47c570d6) ] coclass WINEAudioConverter { }
+[
- threading(both),
- uuid(2eeb4adf-4578-4d10-bca7-bb955f56320a)
+] +coclass CWMADecMediaObject {}; diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c new file mode 100644 index 00000000000..1280d7b1efb --- /dev/null +++ b/dlls/winegstreamer/wma_decoder.c @@ -0,0 +1,36 @@ +/* WMA Decoder Transform
- Copyright 2022 Rémi Bernon 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
- */
+#include "gst_private.h"
+#include "mfapi.h" +#include "mferror.h" +#include "mfobjects.h" +#include "mftransform.h"
+#include "wine/debug.h" +#include "wine/heap.h"
+WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+HRESULT wma_decoder_create(REFIID riid, void **ret) +{
- FIXME("riid %s, ret %p stub!\n", debugstr_guid(riid), ret);
- return E_NOTIMPL;
+}
Qua winegstreamer, this is:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
On 1/26/22 00:38, Zebediah Figura (she/her) wrote:
Qua winegstreamer, this is:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
It looks like this is going to be causing some regression in FFXIV, the game tries to create a WMA IMediaObject from this class id and expects at least COM aggregation to succeed.
Maybe it's better to wait a bit until I sort it out.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Note: As we build FAudio without asserts, this only triggers dbgstr output each time the transform is used, when WMA is played, instead of failing the initialization.
dlls/winegstreamer/wma_decoder.c | 245 ++++++++++++++++++++++++++++++- 1 file changed, 243 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index 1280d7b1efb..c939691c123 100644 --- a/dlls/winegstreamer/wma_decoder.c +++ b/dlls/winegstreamer/wma_decoder.c @@ -23,14 +23,255 @@ #include "mferror.h" #include "mfobjects.h" #include "mftransform.h" +#include "wmcodecdsp.h"
#include "wine/debug.h" #include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
-HRESULT wma_decoder_create(REFIID riid, void **ret) +struct wma_decoder { - FIXME("riid %s, ret %p stub!\n", debugstr_guid(riid), ret); + IMFTransform IMFTransform_iface; + LONG refcount; +}; + +static struct wma_decoder *impl_from_IMFTransform(IMFTransform *iface) +{ + return CONTAINING_RECORD(iface, struct wma_decoder, IMFTransform_iface); +} + +static HRESULT WINAPI wma_decoder_QueryInterface(IMFTransform *iface, REFIID iid, void **out) +{ + struct wma_decoder *decoder = impl_from_IMFTransform(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IMFTransform)) + *out = &decoder->IMFTransform_iface; + else + { + *out = NULL; + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG WINAPI wma_decoder_AddRef(IMFTransform *iface) +{ + struct wma_decoder *decoder = impl_from_IMFTransform(iface); + ULONG refcount = InterlockedIncrement(&decoder->refcount); + + TRACE("iface %p increasing refcount to %u.\n", decoder, refcount); + + return refcount; +} + +static ULONG WINAPI wma_decoder_Release(IMFTransform *iface) +{ + struct wma_decoder *decoder = impl_from_IMFTransform(iface); + ULONG refcount = InterlockedDecrement(&decoder->refcount); + + TRACE("iface %p decreasing refcount to %u.\n", decoder, refcount); + + if (!refcount) + free(decoder); + + return refcount; +} + +static HRESULT WINAPI wma_decoder_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, + DWORD *input_maximum, DWORD *output_minimum, DWORD *output_maximum) +{ + FIXME("iface %p, input_minimum %p, input_maximum %p, output_minimum %p, output_maximum %p stub!\n", + iface, input_minimum, input_maximum, output_minimum, output_maximum); return E_NOTIMPL; } + +static HRESULT WINAPI wma_decoder_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) +{ + FIXME("iface %p, inputs %p, outputs %p stub!\n", iface, inputs, outputs); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs, + DWORD output_size, DWORD *outputs) +{ + FIXME("iface %p, input_size %u, inputs %p, output_size %u, outputs %p stub!\n", iface, + input_size, inputs, output_size, outputs); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) +{ + FIXME("iface %p, id %u, info %p stub!\n", iface, id, info); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) +{ + FIXME("iface %p, id %u, info %p stub!\n", iface, id, info); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) +{ + FIXME("iface %p, attributes %p stub!\n", iface, attributes); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetInputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{ + FIXME("iface %p, id %u, attributes %p stub!\n", iface, id, attributes); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{ + FIXME("iface %p, id %u, attributes %p stub!\n", iface, id, attributes); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_DeleteInputStream(IMFTransform *iface, DWORD id) +{ + FIXME("iface %p, id %u stub!\n", iface, id); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) +{ + FIXME("iface %p, streams %u, ids %p stub!\n", iface, streams, ids); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + FIXME("iface %p, id %u, index %u, type %p stub!\n", iface, id, index, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + FIXME("iface %p, id %u, index %u, type %p stub!\n", iface, id, index, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + FIXME("iface %p, id %u, type %p, flags %#x stub!\n", iface, id, type, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + FIXME("iface %p, id %u, type %p, flags %#x stub!\n", iface, id, type, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + FIXME("iface %p, id %u, type %p stub!\n", iface, id, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + FIXME("iface %p, id %u, type %p stub!\n", iface, id, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) +{ + FIXME("iface %p, id %u, flags %p stub!\n", iface, id, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_GetOutputStatus(IMFTransform *iface, DWORD *flags) +{ + FIXME("iface %p, flags %p stub!\n", iface, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) +{ + FIXME("iface %p, lower %s, upper %s stub!\n", iface, wine_dbgstr_longlong(lower), + wine_dbgstr_longlong(upper)); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) +{ + FIXME("iface %p, id %u, event %p stub!\n", iface, id, event); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) +{ + FIXME("iface %p, message %#x, param %p stub!\n", iface, message, (void *)param); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) +{ + FIXME("iface %p, id %u, sample %p, flags %#x stub!\n", iface, id, sample, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI wma_decoder_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, + MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) +{ + FIXME("iface %p, flags %#x, count %u, samples %p, status %p stub!\n", iface, flags, count, samples, status); + return E_NOTIMPL; +} + +static const IMFTransformVtbl wma_decoder_vtbl = +{ + wma_decoder_QueryInterface, + wma_decoder_AddRef, + wma_decoder_Release, + wma_decoder_GetStreamLimits, + wma_decoder_GetStreamCount, + wma_decoder_GetStreamIDs, + wma_decoder_GetInputStreamInfo, + wma_decoder_GetOutputStreamInfo, + wma_decoder_GetAttributes, + wma_decoder_GetInputStreamAttributes, + wma_decoder_GetOutputStreamAttributes, + wma_decoder_DeleteInputStream, + wma_decoder_AddInputStreams, + wma_decoder_GetInputAvailableType, + wma_decoder_GetOutputAvailableType, + wma_decoder_SetInputType, + wma_decoder_SetOutputType, + wma_decoder_GetInputCurrentType, + wma_decoder_GetOutputCurrentType, + wma_decoder_GetInputStatus, + wma_decoder_GetOutputStatus, + wma_decoder_SetOutputBounds, + wma_decoder_ProcessEvent, + wma_decoder_ProcessMessage, + wma_decoder_ProcessInput, + wma_decoder_ProcessOutput, +}; + +HRESULT wma_decoder_create(REFIID riid, void **ret) +{ + struct wma_decoder *decoder; + + TRACE("riid %s, ret %p.\n", debugstr_guid(riid), ret); + + if (!(decoder = calloc(1, sizeof(*decoder)))) + return E_OUTOFMEMORY; + + decoder->IMFTransform_iface.lpVtbl = &wma_decoder_vtbl; + decoder->refcount = 1; + + *ret = &decoder->IMFTransform_iface; + TRACE("Created decoder %p\n", *ret); + return S_OK; +}
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 20/01/22 11:41, Rémi Bernon ha scritto:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
Note: As we build FAudio without asserts, this only triggers dbgstr output each time the transform is used, when WMA is played, instead of failing the initialization.
dlls/winegstreamer/wma_decoder.c | 245 ++++++++++++++++++++++++++++++- 1 file changed, 243 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index 1280d7b1efb..c939691c123 100644 --- a/dlls/winegstreamer/wma_decoder.c +++ b/dlls/winegstreamer/wma_decoder.c @@ -23,14 +23,255 @@ #include "mferror.h" #include "mfobjects.h" #include "mftransform.h" +#include "wmcodecdsp.h"
#include "wine/debug.h" #include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
-HRESULT wma_decoder_create(REFIID riid, void **ret) +struct wma_decoder {
- FIXME("riid %s, ret %p stub!\n", debugstr_guid(riid), ret);
- IMFTransform IMFTransform_iface;
- LONG refcount;
+};
+static struct wma_decoder *impl_from_IMFTransform(IMFTransform *iface) +{
- return CONTAINING_RECORD(iface, struct wma_decoder, IMFTransform_iface);
+}
+static HRESULT WINAPI wma_decoder_QueryInterface(IMFTransform *iface, REFIID iid, void **out) +{
- struct wma_decoder *decoder = impl_from_IMFTransform(iface);
- TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
- if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IMFTransform))
*out = &decoder->IMFTransform_iface;
- else
- {
*out = NULL;
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
return E_NOINTERFACE;
- }
- IUnknown_AddRef((IUnknown *)*out);
- return S_OK;
+}
+static ULONG WINAPI wma_decoder_AddRef(IMFTransform *iface) +{
- struct wma_decoder *decoder = impl_from_IMFTransform(iface);
- ULONG refcount = InterlockedIncrement(&decoder->refcount);
- TRACE("iface %p increasing refcount to %u.\n", decoder, refcount);
- return refcount;
+}
+static ULONG WINAPI wma_decoder_Release(IMFTransform *iface) +{
- struct wma_decoder *decoder = impl_from_IMFTransform(iface);
- ULONG refcount = InterlockedDecrement(&decoder->refcount);
- TRACE("iface %p decreasing refcount to %u.\n", decoder, refcount);
- if (!refcount)
free(decoder);
- return refcount;
+}
+static HRESULT WINAPI wma_decoder_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum,
DWORD *input_maximum, DWORD *output_minimum, DWORD *output_maximum)
+{
- FIXME("iface %p, input_minimum %p, input_maximum %p, output_minimum %p, output_maximum %p stub!\n",
}iface, input_minimum, input_maximum, output_minimum, output_maximum); return E_NOTIMPL;
+static HRESULT WINAPI wma_decoder_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) +{
- FIXME("iface %p, inputs %p, outputs %p stub!\n", iface, inputs, outputs);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs,
DWORD output_size, DWORD *outputs)
+{
- FIXME("iface %p, input_size %u, inputs %p, output_size %u, outputs %p stub!\n", iface,
input_size, inputs, output_size, outputs);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) +{
- FIXME("iface %p, id %u, info %p stub!\n", iface, id, info);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) +{
- FIXME("iface %p, id %u, info %p stub!\n", iface, id, info);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) +{
- FIXME("iface %p, attributes %p stub!\n", iface, attributes);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetInputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{
- FIXME("iface %p, id %u, attributes %p stub!\n", iface, id, attributes);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{
- FIXME("iface %p, id %u, attributes %p stub!\n", iface, id, attributes);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_DeleteInputStream(IMFTransform *iface, DWORD id) +{
- FIXME("iface %p, id %u stub!\n", iface, id);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) +{
- FIXME("iface %p, streams %u, ids %p stub!\n", iface, streams, ids);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
IMFMediaType **type)
+{
- FIXME("iface %p, id %u, index %u, type %p stub!\n", iface, id, index, type);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
IMFMediaType **type)
+{
- FIXME("iface %p, id %u, index %u, type %p stub!\n", iface, id, index, type);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{
- FIXME("iface %p, id %u, type %p, flags %#x stub!\n", iface, id, type, flags);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{
- FIXME("iface %p, id %u, type %p, flags %#x stub!\n", iface, id, type, flags);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{
- FIXME("iface %p, id %u, type %p stub!\n", iface, id, type);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{
- FIXME("iface %p, id %u, type %p stub!\n", iface, id, type);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) +{
- FIXME("iface %p, id %u, flags %p stub!\n", iface, id, flags);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_GetOutputStatus(IMFTransform *iface, DWORD *flags) +{
- FIXME("iface %p, flags %p stub!\n", iface, flags);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) +{
- FIXME("iface %p, lower %s, upper %s stub!\n", iface, wine_dbgstr_longlong(lower),
wine_dbgstr_longlong(upper));
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) +{
- FIXME("iface %p, id %u, event %p stub!\n", iface, id, event);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) +{
- FIXME("iface %p, message %#x, param %p stub!\n", iface, message, (void *)param);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) +{
- FIXME("iface %p, id %u, sample %p, flags %#x stub!\n", iface, id, sample, flags);
- return E_NOTIMPL;
+}
+static HRESULT WINAPI wma_decoder_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
+{
- FIXME("iface %p, flags %#x, count %u, samples %p, status %p stub!\n", iface, flags, count, samples, status);
- return E_NOTIMPL;
+}
+static const IMFTransformVtbl wma_decoder_vtbl = +{
- wma_decoder_QueryInterface,
- wma_decoder_AddRef,
- wma_decoder_Release,
- wma_decoder_GetStreamLimits,
- wma_decoder_GetStreamCount,
- wma_decoder_GetStreamIDs,
- wma_decoder_GetInputStreamInfo,
- wma_decoder_GetOutputStreamInfo,
- wma_decoder_GetAttributes,
- wma_decoder_GetInputStreamAttributes,
- wma_decoder_GetOutputStreamAttributes,
- wma_decoder_DeleteInputStream,
- wma_decoder_AddInputStreams,
- wma_decoder_GetInputAvailableType,
- wma_decoder_GetOutputAvailableType,
- wma_decoder_SetInputType,
- wma_decoder_SetOutputType,
- wma_decoder_GetInputCurrentType,
- wma_decoder_GetOutputCurrentType,
- wma_decoder_GetInputStatus,
- wma_decoder_GetOutputStatus,
- wma_decoder_SetOutputBounds,
- wma_decoder_ProcessEvent,
- wma_decoder_ProcessMessage,
- wma_decoder_ProcessInput,
- wma_decoder_ProcessOutput,
+};
+HRESULT wma_decoder_create(REFIID riid, void **ret) +{
- struct wma_decoder *decoder;
- TRACE("riid %s, ret %p.\n", debugstr_guid(riid), ret);
- if (!(decoder = calloc(1, sizeof(*decoder))))
return E_OUTOFMEMORY;
- decoder->IMFTransform_iface.lpVtbl = &wma_decoder_vtbl;
- decoder->refcount = 1;
- *ret = &decoder->IMFTransform_iface;
- TRACE("Created decoder %p\n", *ret);
- return S_OK;
+}
Qua winegstreamer, this is:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 20/01/22 11:41, Rémi Bernon ha scritto:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
include/wmcodecdsp.idl | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/wmcodecdsp.idl b/include/wmcodecdsp.idl index 1e43766a358..809e528d7e2 100644 --- a/include/wmcodecdsp.idl +++ b/include/wmcodecdsp.idl @@ -20,6 +20,7 @@ import "mediaobj.idl"; import "strmif.idl";
cpp_quote("DEFINE_GUID(MEDIASUBTYPE_I420,0x30323449,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);") +cpp_quote("DEFINE_GUID(MEDIASUBTYPE_MSAUDIO1,0x00000160,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);")
[ uuid(bbeea841-0a63-4f52-a7ab-a9b3a84ed38a)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
Replying only because following patches depend on it.