mfmediaengine: Implement GetNativeVideoSize().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e1b193d8ba
commit
b793799d3d
|
@ -1,6 +1,6 @@
|
||||||
MODULE = mfmediaengine.dll
|
MODULE = mfmediaengine.dll
|
||||||
IMPORTLIB = mfmediaengine
|
IMPORTLIB = mfmediaengine
|
||||||
IMPORTS = oleaut32 mfplat mf mfuuid uuid
|
IMPORTS = oleaut32 ole32 mfplat mf mfuuid uuid
|
||||||
|
|
||||||
EXTRADLLFLAGS = -mno-cygwin
|
EXTRADLLFLAGS = -mno-cygwin
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,8 @@ enum media_engine_flags
|
||||||
struct video_frame
|
struct video_frame
|
||||||
{
|
{
|
||||||
LONGLONG pts;
|
LONGLONG pts;
|
||||||
|
UINT64 size;
|
||||||
|
TOPOID node_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct media_engine
|
struct media_engine
|
||||||
|
@ -250,6 +252,42 @@ static struct media_engine *impl_from_IMFSampleGrabberSinkCallback(IMFSampleGrab
|
||||||
return CONTAINING_RECORD(iface, struct media_engine, grabber_callback);
|
return CONTAINING_RECORD(iface, struct media_engine, grabber_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void media_engine_get_frame_size(struct media_engine *engine, IMFTopology *topology)
|
||||||
|
{
|
||||||
|
IMFMediaTypeHandler *handler;
|
||||||
|
IMFMediaType *media_type;
|
||||||
|
IMFStreamDescriptor *sd;
|
||||||
|
IMFTopologyNode *node;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
engine->video_frame.size = 0;
|
||||||
|
|
||||||
|
if (FAILED(IMFTopology_GetNodeByID(topology, engine->video_frame.node_id, &node)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
hr = IMFTopologyNode_GetUnknown(node, &MF_TOPONODE_STREAM_DESCRIPTOR,
|
||||||
|
&IID_IMFStreamDescriptor, (void **)&sd);
|
||||||
|
IMFTopologyNode_Release(node);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
|
||||||
|
IMFStreamDescriptor_Release(sd);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
|
||||||
|
IMFMediaTypeHandler_Release(handler);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
WARN("Failed to get current media type %#x.\n", hr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &engine->video_frame.size);
|
||||||
|
IMFMediaType_Release(media_type);
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI media_engine_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
|
static HRESULT WINAPI media_engine_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
|
||||||
{
|
{
|
||||||
if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
|
if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
|
||||||
|
@ -312,9 +350,43 @@ static HRESULT WINAPI media_engine_session_events_Invoke(IMFAsyncCallback *iface
|
||||||
case MESessionTopologyStatus:
|
case MESessionTopologyStatus:
|
||||||
{
|
{
|
||||||
UINT32 topo_status = 0;
|
UINT32 topo_status = 0;
|
||||||
|
IMFTopology *topology;
|
||||||
|
PROPVARIANT value;
|
||||||
|
|
||||||
IMFMediaEvent_GetUINT32(event, &MF_EVENT_TOPOLOGY_STATUS, &topo_status);
|
IMFMediaEvent_GetUINT32(event, &MF_EVENT_TOPOLOGY_STATUS, &topo_status);
|
||||||
if (topo_status == MF_TOPOSTATUS_READY)
|
if (topo_status != MF_TOPOSTATUS_READY)
|
||||||
IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_CANPLAY, 0, 0);
|
break;
|
||||||
|
|
||||||
|
value.vt = VT_EMPTY;
|
||||||
|
if (FAILED(IMFMediaEvent_GetValue(event, &value)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (value.vt != VT_UNKNOWN)
|
||||||
|
{
|
||||||
|
PropVariantClear(&value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
topology = (IMFTopology *)value.punkVal;
|
||||||
|
|
||||||
|
EnterCriticalSection(&engine->cs);
|
||||||
|
|
||||||
|
engine->ready_state = MF_MEDIA_ENGINE_READY_HAVE_METADATA;
|
||||||
|
|
||||||
|
media_engine_get_frame_size(engine, topology);
|
||||||
|
|
||||||
|
IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_DURATIONCHANGE, 0, 0);
|
||||||
|
IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_LOADEDMETADATA, 0, 0);
|
||||||
|
|
||||||
|
engine->ready_state = MF_MEDIA_ENGINE_READY_HAVE_ENOUGH_DATA;
|
||||||
|
|
||||||
|
IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_LOADEDDATA, 0, 0);
|
||||||
|
IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_CANPLAY, 0, 0);
|
||||||
|
|
||||||
|
LeaveCriticalSection(&engine->cs);
|
||||||
|
|
||||||
|
PropVariantClear(&value);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MESessionStarted:
|
case MESessionStarted:
|
||||||
|
@ -461,6 +533,9 @@ static HRESULT media_engine_create_topology(struct media_engine *engine, IMFMedi
|
||||||
UINT64 duration;
|
UINT64 duration;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
engine->video_frame.node_id = 0;
|
||||||
|
engine->video_frame.size = 0;
|
||||||
|
|
||||||
if (FAILED(hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd)))
|
if (FAILED(hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd)))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
|
@ -525,15 +600,6 @@ static HRESULT media_engine_create_topology(struct media_engine *engine, IMFMedi
|
||||||
else
|
else
|
||||||
engine->duration = INFINITY;
|
engine->duration = INFINITY;
|
||||||
|
|
||||||
engine->ready_state = MF_MEDIA_ENGINE_READY_HAVE_METADATA;
|
|
||||||
|
|
||||||
IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_DURATIONCHANGE, 0, 0);
|
|
||||||
IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_LOADEDMETADATA, 0, 0);
|
|
||||||
|
|
||||||
engine->ready_state = MF_MEDIA_ENGINE_READY_HAVE_ENOUGH_DATA;
|
|
||||||
|
|
||||||
IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_LOADEDDATA, 0, 0);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr = MFCreateTopology(&topology)))
|
if (SUCCEEDED(hr = MFCreateTopology(&topology)))
|
||||||
{
|
{
|
||||||
IMFTopologyNode *sar_node = NULL, *audio_src = NULL;
|
IMFTopologyNode *sar_node = NULL, *audio_src = NULL;
|
||||||
|
@ -575,6 +641,9 @@ static HRESULT media_engine_create_topology(struct media_engine *engine, IMFMedi
|
||||||
IMFTopologyNode_ConnectOutput(video_src, 0, grabber_node, 0);
|
IMFTopologyNode_ConnectOutput(video_src, 0, grabber_node, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
IMFTopologyNode_GetTopoNodeID(video_src, &engine->video_frame.node_id);
|
||||||
|
|
||||||
if (grabber_node)
|
if (grabber_node)
|
||||||
IMFTopologyNode_Release(grabber_node);
|
IMFTopologyNode_Release(grabber_node);
|
||||||
if (video_src)
|
if (video_src)
|
||||||
|
@ -1230,9 +1299,27 @@ static BOOL WINAPI media_engine_HasAudio(IMFMediaEngine *iface)
|
||||||
|
|
||||||
static HRESULT WINAPI media_engine_GetNativeVideoSize(IMFMediaEngine *iface, DWORD *cx, DWORD *cy)
|
static HRESULT WINAPI media_engine_GetNativeVideoSize(IMFMediaEngine *iface, DWORD *cx, DWORD *cy)
|
||||||
{
|
{
|
||||||
FIXME("(%p, %p, %p): stub.\n", iface, cx, cy);
|
struct media_engine *engine = impl_from_IMFMediaEngine(iface);
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
return E_NOTIMPL;
|
TRACE("%p, %p, %p.\n", iface, cx, cy);
|
||||||
|
|
||||||
|
if (!cx && !cy)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection(&engine->cs);
|
||||||
|
|
||||||
|
if (!engine->video_frame.size)
|
||||||
|
hr = E_FAIL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cx) *cx = engine->video_frame.size >> 32;
|
||||||
|
if (cy) *cy = engine->video_frame.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&engine->cs);
|
||||||
|
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI media_engine_GetVideoAspectRatio(IMFMediaEngine *iface, DWORD *cx, DWORD *cy)
|
static HRESULT WINAPI media_engine_GetVideoAspectRatio(IMFMediaEngine *iface, DWORD *cx, DWORD *cy)
|
||||||
|
|
Loading…
Reference in New Issue