Commit 44c49b23 authored by Ziqing Hui's avatar Ziqing Hui Committed by Alexandre Julliard

winegstreamer: Add stubs for stream sink.

parent 0aeab6b7
......@@ -19,11 +19,25 @@
#include "gst_private.h"
#include "mferror.h"
#include "mfapi.h"
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
struct stream_sink
{
IMFStreamSink IMFStreamSink_iface;
LONG refcount;
DWORD id;
IMFMediaType *type;
IMFFinalizableMediaSink *media_sink;
struct list entry;
};
struct media_sink
{
IMFFinalizableMediaSink IMFFinalizableMediaSink_iface;
......@@ -32,13 +46,208 @@ struct media_sink
bool shutdown;
IMFByteStream *bytestream;
struct list stream_sinks;
};
static struct stream_sink *impl_from_IMFStreamSink(IMFStreamSink *iface)
{
return CONTAINING_RECORD(iface, struct stream_sink, IMFStreamSink_iface);
}
static struct media_sink *impl_from_IMFFinalizableMediaSink(IMFFinalizableMediaSink *iface)
{
return CONTAINING_RECORD(iface, struct media_sink, IMFFinalizableMediaSink_iface);
}
static HRESULT WINAPI stream_sink_QueryInterface(IMFStreamSink *iface, REFIID riid, void **obj)
{
struct stream_sink *stream_sink = impl_from_IMFStreamSink(iface);
TRACE("iface %p, riid %s, obj %p.\n", iface, debugstr_guid(riid), obj);
if (IsEqualIID(riid, &IID_IMFStreamSink) ||
IsEqualGUID(riid, &IID_IMFMediaEventGenerator) ||
IsEqualIID(riid, &IID_IUnknown))
{
*obj = &stream_sink->IMFStreamSink_iface;
}
else
{
WARN("Unsupported interface %s.\n", debugstr_guid(riid));
*obj = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown *)*obj);
return S_OK;
}
static ULONG WINAPI stream_sink_AddRef(IMFStreamSink *iface)
{
struct stream_sink *stream_sink = impl_from_IMFStreamSink(iface);
ULONG refcount = InterlockedIncrement(&stream_sink->refcount);
TRACE("iface %p, refcount %lu.\n", iface, refcount);
return refcount;
}
static ULONG WINAPI stream_sink_Release(IMFStreamSink *iface)
{
struct stream_sink *stream_sink = impl_from_IMFStreamSink(iface);
ULONG refcount = InterlockedDecrement(&stream_sink->refcount);
TRACE("iface %p, refcount %lu.\n", iface, refcount);
if (!refcount)
{
IMFFinalizableMediaSink_Release(stream_sink->media_sink);
if (stream_sink->type)
IMFMediaType_Release(stream_sink->type);
free(stream_sink);
}
return refcount;
}
static HRESULT WINAPI stream_sink_GetEvent(IMFStreamSink *iface, DWORD flags, IMFMediaEvent **event)
{
FIXME("iface %p, flags %#lx, event %p.\n", iface, flags, event);
return E_NOTIMPL;
}
static HRESULT WINAPI stream_sink_BeginGetEvent(IMFStreamSink *iface, IMFAsyncCallback *callback,
IUnknown *state)
{
FIXME("iface %p, callback %p, state %p.\n", iface, callback, state);
return E_NOTIMPL;
}
static HRESULT WINAPI stream_sink_EndGetEvent(IMFStreamSink *iface, IMFAsyncResult *result,
IMFMediaEvent **event)
{
FIXME("iface %p, result %p, event %p.\n", iface, result, event);
return E_NOTIMPL;
}
static HRESULT WINAPI stream_sink_QueueEvent(IMFStreamSink *iface, MediaEventType event_type,
REFGUID ext_type, HRESULT hr, const PROPVARIANT *value)
{
FIXME("iface %p, event_type %lu, ext_type %s, hr %#lx, value %p.\n",
iface, event_type, debugstr_guid(ext_type), hr, value);
return E_NOTIMPL;
}
static HRESULT WINAPI stream_sink_GetMediaSink(IMFStreamSink *iface, IMFMediaSink **ret)
{
struct stream_sink *stream_sink = impl_from_IMFStreamSink(iface);
TRACE("iface %p, ret %p.\n", iface, ret);
IMFMediaSink_AddRef((*ret = (IMFMediaSink *)stream_sink->media_sink));
return S_OK;
}
static HRESULT WINAPI stream_sink_GetIdentifier(IMFStreamSink *iface, DWORD *identifier)
{
struct stream_sink *stream_sink = impl_from_IMFStreamSink(iface);
TRACE("iface %p, identifier %p.\n", iface, identifier);
*identifier = stream_sink->id;
return S_OK;
}
static HRESULT WINAPI stream_sink_GetMediaTypeHandler(IMFStreamSink *iface, IMFMediaTypeHandler **handler)
{
FIXME("iface %p, handler %p stub!\n", iface, handler);
return E_NOTIMPL;
}
static HRESULT WINAPI stream_sink_ProcessSample(IMFStreamSink *iface, IMFSample *sample)
{
FIXME("iface %p, sample %p stub!\n", iface, sample);
return E_NOTIMPL;
}
static HRESULT WINAPI stream_sink_PlaceMarker(IMFStreamSink *iface, MFSTREAMSINK_MARKER_TYPE marker_type,
const PROPVARIANT *marker_value, const PROPVARIANT *context_value)
{
FIXME("iface %p, marker_type %d, marker_value %p, context_value %p stub!\n",
iface, marker_type, marker_value, context_value);
return E_NOTIMPL;
}
static HRESULT WINAPI stream_sink_Flush(IMFStreamSink *iface)
{
FIXME("iface %p stub!\n", iface);
return E_NOTIMPL;
}
static const IMFStreamSinkVtbl stream_sink_vtbl =
{
stream_sink_QueryInterface,
stream_sink_AddRef,
stream_sink_Release,
stream_sink_GetEvent,
stream_sink_BeginGetEvent,
stream_sink_EndGetEvent,
stream_sink_QueueEvent,
stream_sink_GetMediaSink,
stream_sink_GetIdentifier,
stream_sink_GetMediaTypeHandler,
stream_sink_ProcessSample,
stream_sink_PlaceMarker,
stream_sink_Flush,
};
static HRESULT stream_sink_create(DWORD stream_sink_id, IMFMediaType *media_type, struct media_sink *media_sink,
struct stream_sink **out)
{
struct stream_sink *stream_sink;
TRACE("stream_sink_id %#lx, media_type %p, media_sink %p, out %p.\n",
stream_sink_id, media_type, media_sink, out);
if (!(stream_sink = calloc(1, sizeof(*stream_sink))))
return E_OUTOFMEMORY;
stream_sink->IMFStreamSink_iface.lpVtbl = &stream_sink_vtbl;
stream_sink->refcount = 1;
stream_sink->id = stream_sink_id;
if (media_type)
IMFMediaType_AddRef((stream_sink->type = media_type));
IMFFinalizableMediaSink_AddRef((stream_sink->media_sink = &media_sink->IMFFinalizableMediaSink_iface));
TRACE("Created stream sink %p.\n", stream_sink);
*out = stream_sink;
return S_OK;
}
static struct stream_sink *media_sink_get_stream_sink_by_id(struct media_sink *media_sink, DWORD id)
{
struct stream_sink *stream_sink;
LIST_FOR_EACH_ENTRY(stream_sink, &media_sink->stream_sinks, struct stream_sink, entry)
{
if (stream_sink->id == id)
return stream_sink;
}
return NULL;
}
static HRESULT WINAPI media_sink_QueryInterface(IMFFinalizableMediaSink *iface, REFIID riid, void **obj)
{
TRACE("iface %p, riid %s, obj %p.\n", iface, debugstr_guid(riid), obj);
......@@ -98,10 +307,36 @@ static HRESULT WINAPI media_sink_GetCharacteristics(IMFFinalizableMediaSink *ifa
static HRESULT WINAPI media_sink_AddStreamSink(IMFFinalizableMediaSink *iface, DWORD stream_sink_id,
IMFMediaType *media_type, IMFStreamSink **stream_sink)
{
FIXME("iface %p, stream_sink_id %#lx, media_type %p, stream_sink %p stub!\n",
struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(iface);
struct stream_sink *object;
HRESULT hr;
TRACE("iface %p, stream_sink_id %#lx, media_type %p, stream_sink %p.\n",
iface, stream_sink_id, media_type, stream_sink);
return E_NOTIMPL;
EnterCriticalSection(&media_sink->cs);
if (media_sink_get_stream_sink_by_id(media_sink, stream_sink_id))
{
LeaveCriticalSection(&media_sink->cs);
return MF_E_STREAMSINK_EXISTS;
}
if (FAILED(hr = stream_sink_create(stream_sink_id, media_type, media_sink, &object)))
{
WARN("Failed to create stream sink, hr %#lx.\n", hr);
LeaveCriticalSection(&media_sink->cs);
return hr;
}
list_add_tail(&media_sink->stream_sinks, &object->entry);
LeaveCriticalSection(&media_sink->cs);
if (stream_sink)
IMFStreamSink_AddRef((*stream_sink = &object->IMFStreamSink_iface));
return S_OK;
}
static HRESULT WINAPI media_sink_RemoveStreamSink(IMFFinalizableMediaSink *iface, DWORD stream_sink_id)
......@@ -151,6 +386,7 @@ static HRESULT WINAPI media_sink_GetPresentationClock(IMFFinalizableMediaSink *i
static HRESULT WINAPI media_sink_Shutdown(IMFFinalizableMediaSink *iface)
{
struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(iface);
struct stream_sink *stream_sink, *next;
TRACE("iface %p.\n", iface);
......@@ -162,6 +398,12 @@ static HRESULT WINAPI media_sink_Shutdown(IMFFinalizableMediaSink *iface)
return MF_E_SHUTDOWN;
}
LIST_FOR_EACH_ENTRY_SAFE(stream_sink, next, &media_sink->stream_sinks, struct stream_sink, entry)
{
list_remove(&stream_sink->entry);
IMFStreamSink_Release(&stream_sink->IMFStreamSink_iface);
}
IMFByteStream_Close(media_sink->bytestream);
media_sink->shutdown = TRUE;
......@@ -220,6 +462,7 @@ static HRESULT media_sink_create(IMFByteStream *bytestream, struct media_sink **
InitializeCriticalSection(&media_sink->cs);
media_sink->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": cs");
IMFByteStream_AddRef((media_sink->bytestream = bytestream));
list_init(&media_sink->stream_sinks);
*out = media_sink;
TRACE("Created media sink %p.\n", media_sink);
......@@ -254,6 +497,7 @@ static ULONG WINAPI sink_class_factory_Release(IMFSinkClassFactory *iface)
static HRESULT WINAPI sink_class_factory_CreateMediaSink(IMFSinkClassFactory *iface, IMFByteStream *bytestream,
IMFMediaType *video_type, IMFMediaType *audio_type, IMFMediaSink **out)
{
IMFFinalizableMediaSink *media_sink_iface;
struct media_sink *media_sink;
HRESULT hr;
......@@ -262,8 +506,28 @@ static HRESULT WINAPI sink_class_factory_CreateMediaSink(IMFSinkClassFactory *if
if (FAILED(hr = media_sink_create(bytestream, &media_sink)))
return hr;
media_sink_iface = &media_sink->IMFFinalizableMediaSink_iface;
if (video_type)
{
if (FAILED(hr = IMFFinalizableMediaSink_AddStreamSink(media_sink_iface, 1, video_type, NULL)))
{
IMFFinalizableMediaSink_Shutdown(media_sink_iface);
IMFFinalizableMediaSink_Release(media_sink_iface);
return hr;
}
}
if (audio_type)
{
if (FAILED(hr = IMFFinalizableMediaSink_AddStreamSink(media_sink_iface, 2, audio_type, NULL)))
{
IMFFinalizableMediaSink_Shutdown(media_sink_iface);
IMFFinalizableMediaSink_Release(media_sink_iface);
return hr;
}
}
*out = (IMFMediaSink *)&media_sink->IMFFinalizableMediaSink_iface;
*out = (IMFMediaSink *)media_sink_iface;
return S_OK;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment