winegstreamer: Add a skeleton MPEG audio decoder filter.
Signed-off-by: Anton Baskanov <baskanov@gmail.com> Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
cf849b7308
commit
d7c4fa0d57
|
@ -28,7 +28,7 @@ static IBaseFilter *create_mpeg_audio_codec(void)
|
|||
IBaseFilter *filter = NULL;
|
||||
HRESULT hr = CoCreateInstance(&CLSID_CMpegAudioCodec, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IBaseFilter, (void **)&filter);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
return filter;
|
||||
}
|
||||
|
||||
|
@ -156,12 +156,12 @@ static void test_aggregation(void)
|
|||
filter = (IBaseFilter *)0xdeadbeef;
|
||||
hr = CoCreateInstance(&CLSID_CMpegAudioCodec, &test_outer, CLSCTX_INPROC_SERVER,
|
||||
&IID_IBaseFilter, (void **)&filter);
|
||||
todo_wine ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
|
||||
ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
|
||||
ok(!filter, "Got interface %p.\n", filter);
|
||||
|
||||
hr = CoCreateInstance(&CLSID_CMpegAudioCodec, &test_outer, CLSCTX_INPROC_SERVER,
|
||||
&IID_IUnknown, (void **)&unk);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("Failed to create MPEG audio decoder instance, skipping tests.\n");
|
||||
|
|
|
@ -13,6 +13,7 @@ C_SRCS = \
|
|||
media_source.c \
|
||||
mfplat.c \
|
||||
quartz_parser.c \
|
||||
quartz_transform.c \
|
||||
wg_format.c \
|
||||
wg_parser.c \
|
||||
wg_transform.c \
|
||||
|
|
|
@ -103,6 +103,7 @@ unsigned int wg_format_get_max_size(const struct wg_format *format);
|
|||
|
||||
HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out);
|
||||
HRESULT decodebin_parser_create(IUnknown *outer, IUnknown **out);
|
||||
HRESULT mpeg_audio_codec_create(IUnknown *outer, IUnknown **out);
|
||||
HRESULT mpeg_splitter_create(IUnknown *outer, IUnknown **out);
|
||||
HRESULT wave_parser_create(IUnknown *outer, IUnknown **out);
|
||||
HRESULT wma_decoder_create(IUnknown *outer, IUnknown **out);
|
||||
|
|
|
@ -431,6 +431,7 @@ static const IClassFactoryVtbl class_factory_vtbl =
|
|||
|
||||
static struct class_factory avi_splitter_cf = {{&class_factory_vtbl}, avi_splitter_create};
|
||||
static struct class_factory decodebin_parser_cf = {{&class_factory_vtbl}, decodebin_parser_create};
|
||||
static struct class_factory mpeg_audio_codec_cf = {{&class_factory_vtbl}, mpeg_audio_codec_create};
|
||||
static struct class_factory mpeg_splitter_cf = {{&class_factory_vtbl}, mpeg_splitter_create};
|
||||
static struct class_factory wave_parser_cf = {{&class_factory_vtbl}, wave_parser_create};
|
||||
static struct class_factory wma_decoder_cf = {{&class_factory_vtbl}, wma_decoder_create};
|
||||
|
@ -452,6 +453,8 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
|
|||
factory = &avi_splitter_cf;
|
||||
else if (IsEqualGUID(clsid, &CLSID_decodebin_parser))
|
||||
factory = &decodebin_parser_cf;
|
||||
else if (IsEqualGUID(clsid, &CLSID_CMpegAudioCodec))
|
||||
factory = &mpeg_audio_codec_cf;
|
||||
else if (IsEqualGUID(clsid, &CLSID_MPEG1Splitter))
|
||||
factory = &mpeg_splitter_cf;
|
||||
else if (IsEqualGUID(clsid, &CLSID_WAVEParser))
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* DirectShow transform filters
|
||||
*
|
||||
* Copyright 2022 Anton Baskanov
|
||||
*
|
||||
* 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"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
|
||||
|
||||
struct transform
|
||||
{
|
||||
struct strmbase_filter filter;
|
||||
|
||||
struct strmbase_sink sink;
|
||||
struct strmbase_source source;
|
||||
};
|
||||
|
||||
static inline struct transform *impl_from_strmbase_filter(struct strmbase_filter *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct transform, filter);
|
||||
}
|
||||
|
||||
static struct strmbase_pin *transform_get_pin(struct strmbase_filter *iface, unsigned int index)
|
||||
{
|
||||
struct transform *filter = impl_from_strmbase_filter(iface);
|
||||
if (index == 0)
|
||||
return &filter->sink.pin;
|
||||
if (index == 1)
|
||||
return &filter->source.pin;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void transform_destroy(struct strmbase_filter *iface)
|
||||
{
|
||||
struct transform *filter = impl_from_strmbase_filter(iface);
|
||||
|
||||
strmbase_source_cleanup(&filter->source);
|
||||
strmbase_sink_cleanup(&filter->sink);
|
||||
strmbase_filter_cleanup(&filter->filter);
|
||||
|
||||
free(filter);
|
||||
}
|
||||
|
||||
static const struct strmbase_filter_ops filter_ops =
|
||||
{
|
||||
.filter_get_pin = transform_get_pin,
|
||||
.filter_destroy = transform_destroy,
|
||||
};
|
||||
|
||||
static HRESULT transform_sink_query_interface(struct strmbase_pin *pin, REFIID iid, void **out)
|
||||
{
|
||||
struct transform *filter = impl_from_strmbase_filter(pin->filter);
|
||||
|
||||
if (IsEqualGUID(iid, &IID_IMemInputPin))
|
||||
*out = &filter->sink.IMemInputPin_iface;
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
|
||||
IUnknown_AddRef((IUnknown *)*out);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const struct strmbase_sink_ops sink_ops =
|
||||
{
|
||||
.base.pin_query_interface = transform_sink_query_interface,
|
||||
};
|
||||
|
||||
static const struct strmbase_source_ops source_ops =
|
||||
{
|
||||
.pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
|
||||
.pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
|
||||
};
|
||||
|
||||
static HRESULT transform_create(IUnknown *outer, const CLSID *clsid, struct transform **out)
|
||||
{
|
||||
struct transform *object;
|
||||
|
||||
object = calloc(1, sizeof(*object));
|
||||
if (!object)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
strmbase_filter_init(&object->filter, outer, clsid, &filter_ops);
|
||||
strmbase_sink_init(&object->sink, &object->filter, L"In", &sink_ops, NULL);
|
||||
strmbase_source_init(&object->source, &object->filter, L"Out", &source_ops);
|
||||
|
||||
*out = object;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT mpeg_audio_codec_create(IUnknown *outer, IUnknown **out)
|
||||
{
|
||||
struct transform *object;
|
||||
HRESULT hr;
|
||||
|
||||
hr = transform_create(outer, &CLSID_CMpegAudioCodec, &object);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
wcscpy(object->sink.pin.name, L"XForm In");
|
||||
wcscpy(object->source.pin.name, L"XForm Out");
|
||||
|
||||
TRACE("Created MPEG audio decoder %p.\n", object);
|
||||
*out = &object->filter.IUnknown_inner;
|
||||
return hr;
|
||||
}
|
|
@ -28,6 +28,13 @@
|
|||
]
|
||||
coclass AviSplitter {}
|
||||
|
||||
[
|
||||
helpstring("MPEG Audio Decoder"),
|
||||
threading(both),
|
||||
uuid(4a2286e0-7bef-11ce-9bd9-0000e202599c)
|
||||
]
|
||||
coclass CMpegAudioCodec {}
|
||||
|
||||
[
|
||||
helpstring("MPEG-I Stream Splitter"),
|
||||
threading(both),
|
||||
|
|
Loading…
Reference in New Issue