If there is ever a need to support an un-seekable bytestream, we'll have to use GstAppSrc.
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/winegstreamer/media_source.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index dbc656a24da..df5dedd484d 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1232,6 +1232,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
struct media_source *object = heap_alloc_zero(sizeof(*object)); IMFStreamDescriptor **descriptors = NULL; + DWORD bytestream_caps; unsigned int i; HRESULT hr; int ret; @@ -1239,6 +1240,12 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ if (!object) return E_OUTOFMEMORY;
+ if (FAILED(hr = IMFByteStream_GetCapabilities(bytestream, &bytestream_caps))) + return hr; + + if (!(bytestream_caps & MFBYTESTREAM_IS_SEEKABLE)) + return MF_E_BYTESTREAM_NOT_SEEKABLE; + object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl; object->ref = 1;
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/winegstreamer/media_source.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index df5dedd484d..c69ef5b0873 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1032,12 +1032,14 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO { struct media_source *source = impl_from_IMFMediaSource(iface);
- FIXME("(%p)->(%p): stub\n", source, characteristics); + TRACE("(%p)->(%p)\n", source, characteristics);
if (source->state == SOURCE_SHUTDOWN) return MF_E_SHUTDOWN;
- return E_NOTIMPL; + *characteristics = MFMEDIASOURCE_CAN_SEEK; + + return S_OK; }
static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **descriptor)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
--- dlls/winegstreamer/media_source.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index c69ef5b0873..e1b23c1e92d 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -681,12 +681,15 @@ static HRESULT WINAPI media_stream_GetMediaSource(IMFMediaStream *iface, IMFMedi { struct media_stream *stream = impl_from_IMFMediaStream(iface);
- FIXME("stub (%p)->(%p)\n", stream, source); + TRACE("(%p)->(%p)\n", stream, source);
if (stream->state == STREAM_SHUTDOWN) return MF_E_SHUTDOWN;
- return E_NOTIMPL; + IMFMediaSource_AddRef(&stream->parent_source->IMFMediaSource_iface); + *source = &stream->parent_source->IMFMediaSource_iface; + + return S_OK; }
static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IMFStreamDescriptor **descriptor)
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- v2: Address nits. --- dlls/winegstreamer/media_source.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index e1b23c1e92d..7755282c01f 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1237,6 +1237,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
struct media_source *object = heap_alloc_zero(sizeof(*object)); IMFStreamDescriptor **descriptors = NULL; + gint64 total_pres_time = 0; DWORD bytestream_caps; unsigned int i; HRESULT hr; @@ -1354,6 +1355,25 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ heap_free(descriptors); descriptors = NULL;
+ for (i = 0; i < object->stream_count; i++) + { + gint64 stream_pres_time; + if (gst_pad_query_duration(object->streams[i]->their_src, GST_FORMAT_TIME, &stream_pres_time)) + { + TRACE("Stream %u has duration %llu\n", i, (unsigned long long int) stream_pres_time); + + if (stream_pres_time > total_pres_time) + total_pres_time = stream_pres_time; + } + else + { + WARN("Unable to get presentation time of stream %u\n", i); + } + } + + if (object->stream_count) + IMFPresentationDescriptor_SetUINT64(object->pres_desc, &MF_PD_DURATION, total_pres_time / 100); + object->state = SOURCE_STOPPED;
*out_media_source = object;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/winegstreamer/media_source.c | 111 ++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 7755282c01f..4664b8a0156 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -91,6 +91,8 @@ struct source_async_command struct media_source { IMFMediaSource IMFMediaSource_iface; + IMFGetService IMFGetService_iface; + IMFSeekInfo IMFSeekInfo_iface; IMFAsyncCallback async_commands_callback; LONG ref; DWORD async_commands_queue; @@ -123,6 +125,16 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface); }
+static inline struct media_source *impl_from_IMFGetService(IMFGetService *iface) +{ + return CONTAINING_RECORD(iface, struct media_source, IMFGetService_iface); +} + +static inline struct media_source *impl_from_IMFSeekInfo(IMFSeekInfo *iface) +{ + return CONTAINING_RECORD(iface, struct media_source, IMFSeekInfo_iface); +} + static inline struct media_source *impl_from_async_commands_callback_IMFAsyncCallback(IMFAsyncCallback *iface) { return CONTAINING_RECORD(iface, struct media_source, async_commands_callback); @@ -956,6 +968,10 @@ static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID { *out = &source->IMFMediaSource_iface; } + else if(IsEqualIID(riid, &IID_IMFGetService)) + { + *out = &source->IMFGetService_iface; + } else { FIXME("(%s, %p)\n", debugstr_guid(riid), out); @@ -1185,6 +1201,99 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl = media_source_Shutdown, };
+static HRESULT WINAPI source_get_service_QueryInterface(IMFGetService *iface, REFIID riid, void **obj) +{ + struct media_source *source = impl_from_IMFGetService(iface); + return IMFMediaSource_QueryInterface(&source->IMFMediaSource_iface, riid, obj); +} + +static ULONG WINAPI source_get_service_AddRef(IMFGetService *iface) +{ + struct media_source *source = impl_from_IMFGetService(iface); + return IMFMediaSource_AddRef(&source->IMFMediaSource_iface); +} + +static ULONG WINAPI source_get_service_Release(IMFGetService *iface) +{ + struct media_source *source = impl_from_IMFGetService(iface); + return IMFMediaSource_Release(&source->IMFMediaSource_iface); +} + +static HRESULT WINAPI source_get_service_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj) +{ + struct media_source *source = impl_from_IMFGetService(iface); + + TRACE("(%p)->(%s, %s, %p)\n", source, debugstr_guid(service), debugstr_guid(riid), obj); + + if (source->state == SOURCE_SHUTDOWN) + return MF_E_SHUTDOWN; + + *obj = NULL; + + if (IsEqualIID(service, &MF_SCRUBBING_SERVICE)) + { + if (IsEqualIID(riid, &IID_IMFSeekInfo)) + { + *obj = &source->IMFSeekInfo_iface; + } + } + + if (*obj) + IUnknown_AddRef((IUnknown*) *obj); + + return *obj ? S_OK : E_NOINTERFACE; +} + +static const IMFGetServiceVtbl IMFGetService_vtbl = +{ + source_get_service_QueryInterface, + source_get_service_AddRef, + source_get_service_Release, + source_get_service_GetService, +}; + +static HRESULT WINAPI source_seek_info_QueryInterface(IMFSeekInfo *iface, REFIID riid, void **obj) +{ + struct media_source *source = impl_from_IMFSeekInfo(iface); + return IMFMediaSource_QueryInterface(&source->IMFMediaSource_iface, riid, obj); +} + +static ULONG WINAPI source_seek_info_AddRef(IMFSeekInfo *iface) +{ + struct media_source *source = impl_from_IMFSeekInfo(iface); + return IMFMediaSource_AddRef(&source->IMFMediaSource_iface); +} + +static ULONG WINAPI source_seek_info_Release(IMFSeekInfo *iface) +{ + struct media_source *source = impl_from_IMFSeekInfo(iface); + return IMFMediaSource_Release(&source->IMFMediaSource_iface); +} + +static HRESULT WINAPI source_seek_info_GetNearestKeyFrames(IMFSeekInfo *iface, const GUID *format, + const PROPVARIANT *position, PROPVARIANT *prev_frame, PROPVARIANT *next_frame) +{ + struct media_source *source = impl_from_IMFSeekInfo(iface); + + FIXME("(%p)->(%s, %p, %p, %p) - semi-stub\n", source, debugstr_guid(format), position, prev_frame, next_frame); + + if (source->state == SOURCE_SHUTDOWN) + return MF_E_SHUTDOWN; + + PropVariantCopy(prev_frame, position); + PropVariantCopy(next_frame, position); + + return S_OK; +} + +static const IMFSeekInfoVtbl IMFSeekInfo_vtbl = +{ + source_seek_info_QueryInterface, + source_seek_info_AddRef, + source_seek_info_Release, + source_seek_info_GetNearestKeyFrames, +}; + static void stream_added(GstElement *element, GstPad *pad, gpointer user) { struct media_source *source = user; @@ -1253,6 +1362,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ return MF_E_BYTESTREAM_NOT_SEEKABLE;
object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; + object->IMFGetService_iface.lpVtbl = &IMFGetService_vtbl; + object->IMFSeekInfo_iface.lpVtbl = &IMFSeekInfo_vtbl; object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl; object->ref = 1; object->byte_stream = bytestream;
On 11/2/20 1:34 PM, Derek Lesho wrote:
If there is ever a need to support an un-seekable bytestream, we'll have to use GstAppSrc.
Well, no, not really, you can push the buffers yourself. More saliently, I'm not sure that GstAppSrc provides a lot of benefit, either. In order for downstream parser elements to use pull mode, you need to use "random-access" scheduling, but that requires that you're able to seek the upstream source, so you'd basically need to use two different code paths anyway.
Signed-off-by: Derek Lesho dlesho@codeweavers.com
dlls/winegstreamer/media_source.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index dbc656a24da..df5dedd484d 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1232,6 +1232,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
struct media_source *object = heap_alloc_zero(sizeof(*object)); IMFStreamDescriptor **descriptors = NULL;
- DWORD bytestream_caps; unsigned int i; HRESULT hr; int ret;
@@ -1239,6 +1240,12 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ if (!object) return E_OUTOFMEMORY;
- if (FAILED(hr = IMFByteStream_GetCapabilities(bytestream, &bytestream_caps)))
return hr;
- if (!(bytestream_caps & MFBYTESTREAM_IS_SEEKABLE))
return MF_E_BYTESTREAM_NOT_SEEKABLE;
- object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl; object->ref = 1;
On 11/2/20 1:34 PM, Derek Lesho wrote:
If there is ever a need to support an un-seekable bytestream, we'll have to use GstAppSrc.
Signed-off-by: Derek Lesho dlesho@codeweavers.com
dlls/winegstreamer/media_source.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index dbc656a24da..df5dedd484d 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1232,6 +1232,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
struct media_source *object = heap_alloc_zero(sizeof(*object)); IMFStreamDescriptor **descriptors = NULL;
- DWORD bytestream_caps; unsigned int i; HRESULT hr; int ret;
@@ -1239,6 +1240,12 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ if (!object) return E_OUTOFMEMORY;
- if (FAILED(hr = IMFByteStream_GetCapabilities(bytestream, &bytestream_caps)))
return hr;
- if (!(bytestream_caps & MFBYTESTREAM_IS_SEEKABLE))
As a further comment, unless this is something that Windows media sources don't support either, I suspect this deserves a FIXME.
return MF_E_BYTESTREAM_NOT_SEEKABLE;
- object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl; object->ref = 1;
On 11/2/20 2:41 PM, Zebediah Figura wrote:
On 11/2/20 1:34 PM, Derek Lesho wrote:
If there is ever a need to support an un-seekable bytestream, we'll have to use GstAppSrc.
Signed-off-by: Derek Lesho dlesho@codeweavers.com
dlls/winegstreamer/media_source.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index dbc656a24da..df5dedd484d 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1232,6 +1232,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
struct media_source *object = heap_alloc_zero(sizeof(*object)); IMFStreamDescriptor **descriptors = NULL;
- DWORD bytestream_caps; unsigned int i; HRESULT hr; int ret;
@@ -1239,6 +1240,12 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ if (!object) return E_OUTOFMEMORY;
- if (FAILED(hr = IMFByteStream_GetCapabilities(bytestream, &bytestream_caps)))
return hr;
- if (!(bytestream_caps & MFBYTESTREAM_IS_SEEKABLE))
As a further comment, unless this is something that Windows media sources don't support either, I suspect this deserves a FIXME.
https://stackoverflow.com/questions/41406319/source-reader-and-custom-non-se...
Seems like not all windows media sources support this.
return MF_E_BYTESTREAM_NOT_SEEKABLE;
object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl; object->ref = 1;
On 11/2/20 3:14 PM, Derek Lesho wrote:
On 11/2/20 2:41 PM, Zebediah Figura wrote:
On 11/2/20 1:34 PM, Derek Lesho wrote:
If there is ever a need to support an un-seekable bytestream, we'll have to use GstAppSrc.
Signed-off-by: Derek Lesho dlesho@codeweavers.com
dlls/winegstreamer/media_source.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index dbc656a24da..df5dedd484d 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1232,6 +1232,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ struct media_source *object = heap_alloc_zero(sizeof(*object)); IMFStreamDescriptor **descriptors = NULL; + DWORD bytestream_caps; unsigned int i; HRESULT hr; int ret; @@ -1239,6 +1240,12 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ if (!object) return E_OUTOFMEMORY; + if (FAILED(hr = IMFByteStream_GetCapabilities(bytestream, &bytestream_caps))) + return hr;
+ if (!(bytestream_caps & MFBYTESTREAM_IS_SEEKABLE))
As a further comment, unless this is something that Windows media sources don't support either, I suspect this deserves a FIXME.
https://stackoverflow.com/questions/41406319/source-reader-and-custom-non-se...
Seems like not all windows media sources support this.
Sure, but if even some do, I would expect that an application *might* depend on that, enough that it's worth complaining loudly about if it happens.
+ return MF_E_BYTESTREAM_NOT_SEEKABLE;
object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl; object->ref = 1;