[PATCH 08/16] winegstreamer: Implement media source on gstreamer.

Nikolay Sivov nsivov at codeweavers.com
Thu Mar 26 00:23:00 CDT 2020


On 3/26/20 3:12 AM, Derek Lesho wrote:
> +static ULONG WINAPI media_stream_Release(IMFMediaStream *iface)
> +{
> +    struct media_stream *This = impl_from_IMFMediaStream(iface);
> +
> +    ULONG ref = InterlockedDecrement(&This->ref);
> +
> +    TRACE("(%p) ref=%u\n", This, ref);
> +
> +    if (!ref)
> +    {
> +        if (This->state != STREAM_SHUTDOWN)
> +            ERR("incomplete cleanup\n");
> +        heap_free(This);
> +    }
> +
> +    return ref;
> +}
Error message here is redundant I think. The point of shutdown is to 
break circular references,
where source holds streams references and every stream hold source 
reference. So in theory
you shouldn't be able to release unless you shut it down.

> +static HRESULT WINAPI media_stream_GetEvent(IMFMediaStream *iface, DWORD flags, IMFMediaEvent **event)
> +{
> +    struct media_stream *This = impl_from_IMFMediaStream(iface);
> +
> +    TRACE("(%p)->(%#x, %p)\n", This, flags, event);
> +
> +    if (This->state == STREAM_SHUTDOWN)
> +        return MF_E_SHUTDOWN;
> +
> +    return IMFMediaEventQueue_GetEvent(This->event_queue, flags, event);
> +}
Same as with the source, you only need to shutdown the queue and it will 
return MF_E_SHUTDOWN for you.

> +static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IMFStreamDescriptor **descriptor)
> +{
> +    struct media_stream *This = impl_from_IMFMediaStream(iface);
> +
> +    TRACE("(%p)->(%p)\n", This, descriptor);
> +
> +    if (This->state == STREAM_SHUTDOWN)
> +        return MF_E_SHUTDOWN;
> +
> +    IMFStreamDescriptor_AddRef(This->descriptor);
> +    *descriptor = This->descriptor;
> +
> +    return S_OK;
> +}
It's not obvious that it's correct but could be problematic to test 
properly, because it could differ between implementations.

> +    req = heap_alloc(sizeof(*req));
> +    if (token)
> +        IUnknown_AddRef(token);
> +    req->token = token;
> +    list_add_tail(&This->sample_requests, &req->entry);
This should be protected, there is no guarantee client is using the same 
thread to make requests, or serializes them.

> @@ -118,28 +684,102 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO
>   {
>       struct media_source *This = impl_from_IMFMediaSource(iface);
>   
> -    FIXME("(%p)->(%p): stub\n", This, characteristics);
> +    TRACE("(%p)->(%p)\n", This, characteristics);
>   
> -    return E_NOTIMPL;
> +    if (This->state == SOURCE_SHUTDOWN)
> +        return MF_E_SHUTDOWN;
> +
> +    *characteristics = 0;
> +
> +    return S_OK;
>   }
Returning 0 flags will prevent seeking. It should be derived from 
bytestream caps + gstreamer object constraints if any. There is a number 
of flags,
but CAN_PAUSE/CAN_SEEK are probably most important ones.

>   static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **descriptor)
>   {
>       struct media_source *This = impl_from_IMFMediaSource(iface);
>   
> -    FIXME("(%p)->(%p): stub\n", This, descriptor);
> +    TRACE("(%p)->(%p)\n", This, descriptor);
>   
> -    return E_NOTIMPL;
> +    if (This->state == SOURCE_SHUTDOWN)
> +        return MF_E_SHUTDOWN;
> +
> +    if (!(This->pres_desc))
> +    {
> +        return MF_E_NOT_INITIALIZED;
> +    }
> +
> +    IMFPresentationDescriptor_Clone(This->pres_desc, descriptor);
> +
> +    return S_OK;
>   }
Is NOT_INITIALIZED path reachable? I think it's generally assumed that 
once you got a source you can get its descriptor, even if stream 
configuration
can change dynamically later.



More information about the wine-devel mailing list