Rémi Bernon : qasf: Implement ASF Reader SourceSeeking stubs.
Alexandre Julliard
julliard at winehq.org
Tue Aug 16 16:02:12 CDT 2022
Module: wine
Branch: master
Commit: 9b2606f3ffd652b87c5cd1b9d7552e112750567f
URL: https://gitlab.winehq.org/wine/wine/-/commit/9b2606f3ffd652b87c5cd1b9d7552e112750567f
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Fri May 27 10:45:33 2022 +0200
qasf: Implement ASF Reader SourceSeeking stubs.
---
dlls/qasf/asfreader.c | 131 ++++++++++++++++++++++++++++++++++++++++++++
dlls/qasf/tests/asfreader.c | 1 -
2 files changed, 131 insertions(+), 1 deletion(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c
index 29a695de77f..7bc57a2d500 100644
--- a/dlls/qasf/asfreader.c
+++ b/dlls/qasf/asfreader.c
@@ -27,6 +27,27 @@
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+static inline const char *debugstr_time(REFERENCE_TIME time)
+{
+ ULONGLONG abstime = time >= 0 ? time : -time;
+ unsigned int i = 0, j = 0;
+ char buffer[23], rev[23];
+
+ while (abstime || i <= 8)
+ {
+ buffer[i++] = '0' + (abstime % 10);
+ abstime /= 10;
+ if (i == 7) buffer[i++] = '.';
+ }
+ if (time < 0) buffer[i++] = '-';
+
+ while (i--) rev[j++] = buffer[i];
+ while (rev[j-1] == '0' && rev[j-2] != '.') --j;
+ rev[j] = 0;
+
+ return wine_dbg_sprintf("%s", rev);
+}
+
struct buffer
{
INSSBuffer INSSBuffer_iface;
@@ -159,6 +180,7 @@ static struct buffer *unsafe_impl_from_INSSBuffer(INSSBuffer *iface)
struct asf_stream
{
struct strmbase_source source;
+ struct SourceSeeking seek;
DWORD index;
};
@@ -266,6 +288,93 @@ static HRESULT asf_stream_get_media_type(struct strmbase_pin *iface, unsigned in
return hr;
}
+static HRESULT asf_stream_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
+{
+ struct asf_stream *stream = impl_from_strmbase_pin(iface);
+
+ if (IsEqualGUID(iid, &IID_IMediaSeeking))
+ *out = &stream->seek.IMediaSeeking_iface;
+ else
+ return E_NOINTERFACE;
+
+ IUnknown_AddRef((IUnknown *)*out);
+ return S_OK;
+}
+
+static inline struct asf_stream *impl_from_IMediaSeeking(IMediaSeeking *iface)
+{
+ return CONTAINING_RECORD(iface, struct asf_stream, seek.IMediaSeeking_iface);
+}
+
+static HRESULT WINAPI media_seeking_ChangeCurrent(IMediaSeeking *iface)
+{
+ FIXME("iface %p stub!\n", iface);
+ return S_OK;
+}
+
+static HRESULT WINAPI media_seeking_ChangeStop(IMediaSeeking *iface)
+{
+ FIXME("iface %p stub!\n", iface);
+ return S_OK;
+}
+
+static HRESULT WINAPI media_seeking_ChangeRate(IMediaSeeking *iface)
+{
+ FIXME("iface %p stub!\n", iface);
+ return S_OK;
+}
+
+static HRESULT WINAPI media_seeking_QueryInterface(IMediaSeeking *iface, REFIID riid, void **ppv)
+{
+ struct asf_stream *impl = impl_from_IMediaSeeking(iface);
+ return IUnknown_QueryInterface(&impl->source.pin.IPin_iface, riid, ppv);
+}
+
+static ULONG WINAPI media_seeking_AddRef(IMediaSeeking *iface)
+{
+ struct asf_stream *impl = impl_from_IMediaSeeking(iface);
+ return IUnknown_AddRef(&impl->source.pin.IPin_iface);
+}
+
+static ULONG WINAPI media_seeking_Release(IMediaSeeking *iface)
+{
+ struct asf_stream *impl = impl_from_IMediaSeeking(iface);
+ return IUnknown_Release(&impl->source.pin.IPin_iface);
+}
+
+static HRESULT WINAPI media_seeking_SetPositions(IMediaSeeking *iface,
+ LONGLONG *current, DWORD current_flags, LONGLONG *stop, DWORD stop_flags)
+{
+ FIXME("iface %p, current %s, current_flags %#lx, stop %s, stop_flags %#lx stub!\n",
+ iface, current ? debugstr_time(*current) : "<null>", current_flags,
+ stop ? debugstr_time(*stop) : "<null>", stop_flags);
+ return SourceSeekingImpl_SetPositions(iface, current, current_flags, stop, stop_flags);
+}
+
+static const IMediaSeekingVtbl media_seeking_vtbl =
+{
+ media_seeking_QueryInterface,
+ media_seeking_AddRef,
+ media_seeking_Release,
+ SourceSeekingImpl_GetCapabilities,
+ SourceSeekingImpl_CheckCapabilities,
+ SourceSeekingImpl_IsFormatSupported,
+ SourceSeekingImpl_QueryPreferredFormat,
+ SourceSeekingImpl_GetTimeFormat,
+ SourceSeekingImpl_IsUsingTimeFormat,
+ SourceSeekingImpl_SetTimeFormat,
+ SourceSeekingImpl_GetDuration,
+ SourceSeekingImpl_GetStopPosition,
+ SourceSeekingImpl_GetCurrentPosition,
+ SourceSeekingImpl_ConvertTimeFormat,
+ media_seeking_SetPositions,
+ SourceSeekingImpl_GetPositions,
+ SourceSeekingImpl_GetAvailable,
+ SourceSeekingImpl_SetRate,
+ SourceSeekingImpl_GetRate,
+ SourceSeekingImpl_GetPreroll,
+};
+
static inline struct asf_reader *impl_from_strmbase_filter(struct strmbase_filter *iface)
{
return CONTAINING_RECORD(iface, struct asf_reader, filter);
@@ -492,6 +601,7 @@ static const struct strmbase_source_ops source_ops =
{
.base.pin_query_accept = asf_stream_query_accept,
.base.pin_get_media_type = asf_stream_get_media_type,
+ .base.pin_query_interface = asf_stream_query_interface,
.pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
.pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
.pfnDecideBufferSize = asf_reader_DecideBufferSize,
@@ -668,8 +778,10 @@ static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STA
{
struct asf_reader *filter = impl_from_IWMReaderCallback(iface)->filter;
AM_MEDIA_TYPE stream_media_type = {{0}};
+ IWMHeaderInfo *header_info;
DWORD i, stream_count;
WCHAR name[MAX_PATH];
+ QWORD duration;
HRESULT hr;
TRACE("iface %p, status %d, result %#lx, type %d, value %p, context %p.\n",
@@ -689,6 +801,20 @@ static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STA
stream_count = ARRAY_SIZE(filter->streams);
}
+ if (FAILED(hr = IWMReader_QueryInterface(filter->reader, &IID_IWMHeaderInfo,
+ (void **)&header_info)))
+ duration = 0;
+ else
+ {
+ WMT_ATTR_DATATYPE type = WMT_TYPE_QWORD;
+ WORD index = 0, size = sizeof(duration);
+
+ if (FAILED(IWMHeaderInfo_GetAttributeByName(header_info, &index, L"Duration",
+ &type, (BYTE *)&duration, &size )))
+ duration = 0;
+ IWMHeaderInfo_Release(header_info);
+ }
+
for (i = 0; i < stream_count; ++i)
{
struct asf_stream *stream = filter->streams + i;
@@ -702,6 +828,11 @@ static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STA
FreeMediaType(&stream_media_type);
strmbase_source_init(&stream->source, &filter->filter, name, &source_ops);
+ strmbase_seeking_init(&stream->seek, &media_seeking_vtbl, media_seeking_ChangeStop,
+ media_seeking_ChangeCurrent, media_seeking_ChangeRate);
+ stream->seek.llCurrent = 0;
+ stream->seek.llDuration = duration;
+ stream->seek.llStop = duration;
}
filter->stream_count = stream_count;
BaseFilterImpl_IncrementPinVersion(&filter->filter);
diff --git a/dlls/qasf/tests/asfreader.c b/dlls/qasf/tests/asfreader.c
index ed78a856003..3a2e18a3054 100644
--- a/dlls/qasf/tests/asfreader.c
+++ b/dlls/qasf/tests/asfreader.c
@@ -258,7 +258,6 @@ static void check_pin(IPin *pin, IBaseFilter *expect_filter, PIN_DIRECTION expec
check_interface(pin, &IID_IPin, TRUE);
check_interface(pin, &IID_IUnknown, TRUE);
- todo_wine
check_interface(pin, &IID_IMediaSeeking, TRUE);
todo_wine
check_interface(pin, &IID_IQualityControl, TRUE);
More information about the wine-cvs
mailing list