BTW, the wine-bug tag in the comment is not using usual capitalization.

On Mon, Jun 8, 2020, 10:28 AM Zebediah Figura <z.figura12@gmail.com> wrote:
From: Gijs Vermeulen <gijsvrm@gmail.com>

wine-bug: https://bugs.winehq.org/show_bug.cgi?id=42372
Signed-off-by: Gijs Vermeulen <gijsvrm@gmail.com>
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
v2: Avoid Hungarian notation and "This"; use a more readable trace format.

������dlls/quartz/filtergraph.c������ ������ ������ ������| 57 ++++++++++++++++++++++++++++++++-
������dlls/quartz/tests/filtergraph.c |������ 1 +
������include/axextend.idl������ ������ ������ ������ ������ ������ | 13 ++++++++
������3 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index 6217516db1..918c41a3d6 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -181,7 +181,7 @@ typedef struct _IFilterGraphImpl {
������ ������ ������/* IRegisterServiceProvider */
������ ������ ������/* IResourceManager */
������ ������ ������/* IServiceProvider */
-������ ������ /* IVideoFrameStep */
+������ ������ IVideoFrameStep IVideoFrameStep_iface;

������ ������ ������IUnknown *outer_unk;
������ ������ ������LONG ref;
@@ -454,6 +454,9 @@ static HRESULT WINAPI FilterGraphInner_QueryInterface(IUnknown *iface, REFIID ri
������ ������ ������} else if (IsEqualGUID(&IID_IGraphVersion, riid)) {
������ ������ ������ ������ ������*ppvObj = &This->IGraphVersion_iface;
������ ������ ������ ������ ������TRACE("������ ������returning IGraphVersion interface (%p)\n", *ppvObj);
+������ ������ } else if (IsEqualGUID(&IID_IVideoFrameStep, riid)) {
+������ ������ ������ ������ *ppvObj = &This->IVideoFrameStep_iface;
+������ ������ ������ ������ TRACE("������ ������returning IVideoFrameStep interface (%p)\n", *ppvObj);
������ ������ ������} else {
������ ������ ������ ������ ������*ppvObj = NULL;
������ ������ ������ ������ FIXME("unknown interface %s\n", debugstr_guid(riid));
@@ -5638,6 +5641,57 @@ static const IGraphVersionVtbl IGraphVersion_VTable =
������ ������ ������GraphVersion_QueryVersion,
������};

+static IFilterGraphImpl *impl_from_IVideoFrameStep(IVideoFrameStep *iface)
+{
+������ ������ return CONTAINING_RECORD(iface, IFilterGraphImpl, IVideoFrameStep_iface);
+}
+
+static HRESULT WINAPI VideoFrameStep_QueryInterface(IVideoFrameStep *iface, REFIID iid, void **out)
+{
+������ ������ IFilterGraphImpl *graph = impl_from_IVideoFrameStep(iface);
+������ ������ return IUnknown_QueryInterface(graph->outer_unk, iid, out);
+}
+
+static ULONG WINAPI VideoFrameStep_AddRef(IVideoFrameStep *iface)
+{
+������ ������ IFilterGraphImpl *graph = impl_from_IVideoFrameStep(iface);
+������ ������ return IUnknown_AddRef(graph->outer_unk);
+}
+
+static ULONG WINAPI VideoFrameStep_Release(IVideoFrameStep *iface)
+{
+������ ������ IFilterGraphImpl *graph = impl_from_IVideoFrameStep(iface);
+������ ������ return IUnknown_Release(graph->outer_unk);
+}
+
+static HRESULT WINAPI VideoFrameStep_Step(IVideoFrameStep *iface, DWORD frame_count, IUnknown *filter)
+{
+������ ������ FIXME("iface %p, frame_count %u, filter %p, stub!\n", iface, frame_count, filter);
+������ ������ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI VideoFrameStep_CanStep(IVideoFrameStep *iface, LONG multiple, IUnknown *filter)
+{
+������ ������ FIXME("iface %p, multiple %d, filter %p, stub!\n", iface, multiple, filter);
+������ ������ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI VideoFrameStep_CancelStep(IVideoFrameStep *iface)
+{
+������ ������ FIXME("iface %p, stub!\n", iface);
+������ ������ return E_NOTIMPL;
+}
+
+static const IVideoFrameStepVtbl VideoFrameStep_vtbl =
+{
+������ ������ VideoFrameStep_QueryInterface,
+������ ������ VideoFrameStep_AddRef,
+������ ������ VideoFrameStep_Release,
+������ ������ VideoFrameStep_Step,
+������ ������ VideoFrameStep_CanStep,
+������ ������ VideoFrameStep_CancelStep
+};
+
������static const IUnknownVtbl IInner_VTable =
������{
������ ������ ������FilterGraphInner_QueryInterface,
@@ -5668,6 +5722,7 @@ static HRESULT filter_graph_common_create(IUnknown *outer, IUnknown **out, BOOL
������ ������ ������fimpl->IMediaPosition_iface.lpVtbl = &IMediaPosition_VTable;
������ ������ ������fimpl->IObjectWithSite_iface.lpVtbl = &IObjectWithSite_VTable;
������ ������ ������fimpl->IGraphVersion_iface.lpVtbl = &IGraphVersion_VTable;
+������ ������ fimpl->IVideoFrameStep_iface.lpVtbl = &VideoFrameStep_vtbl;
������ ������ ������fimpl->ref = 1;
������ ������ ������list_init(&fimpl->filters);
������ ������ ������list_init(&fimpl->sorted_filters);
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c
index f0aa084192..a3378efe0b 100644
--- a/dlls/quartz/tests/filtergraph.c
+++ b/dlls/quartz/tests/filtergraph.c
@@ -125,6 +125,7 @@ static void test_interfaces(void)
������ ������ ������check_interface(graph, &IID_IMediaPosition, TRUE);
������ ������ ������check_interface(graph, &IID_IMediaSeeking, TRUE);
������ ������ ������check_interface(graph, &IID_IObjectWithSite, TRUE);
+������ ������ check_interface(graph, &IID_IVideoFrameStep, TRUE);
������ ������ ������check_interface(graph, &IID_IVideoWindow, TRUE);

������ ������ ������check_interface(graph, &IID_IBaseFilter, FALSE);
diff --git a/include/axextend.idl b/include/axextend.idl
index 8b46d665b5..7630ea247c 100644
--- a/include/axextend.idl
+++ b/include/axextend.idl
@@ -1471,3 +1471,16 @@ interface IAMTVTuner : IAMTuner
������ ������ ������HRESULT get_VideoFrequency([out] long *freq);
������ ������ ������HRESULT get_AudioFrequency([out] long *freq);
������}
+
+[
+������ ������ local,
+������ ������ object,
+������ ������ uuid(e46a9787-2b71-444d-a4b5-1fab7b708d6a),
+������ ������ pointer_default(unique),
+]
+interface IVideoFrameStep : IUnknown
+{
+������ ������ HRESULT Step(DWORD frame_count, [in] IUnknown *filter);
+������ ������ HRESULT CanStep(long multiple, [in] IUnknown *filter);
+������ ������ HRESULT CancelStep();
+}
--
2.27.0