[PATCH v2 1/5] winegstreamer: Insert videoconvert into decoded-video streams.
Zebediah Figura
z.figura12 at gmail.com
Tue Oct 6 21:08:24 CDT 2020
On 10/6/20 10:59 AM, Derek Lesho wrote:
> Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
> ---
> v2:
> - Use fixed list of supported formats in the videoconvert path instead of querying the template.
> - Moved code setting "caps" appsink property to patch 4, where it begins to be used.
> - Addressed some comments.
> ---
> dlls/winegstreamer/media_source.c | 124 ++++++++++++++++++++++++++----
> 1 file changed, 110 insertions(+), 14 deletions(-)
>
> diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
> index 5f3c43a0204..cbee412030d 100644
> --- a/dlls/winegstreamer/media_source.c
> +++ b/dlls/winegstreamer/media_source.c
> @@ -384,6 +384,43 @@ static const IMFMediaStreamVtbl media_stream_vtbl =
> media_stream_RequestSample
> };
>
> +/* Setup a chain of elements which should hopefully allow transformations to any IMFMediaType
> + the user throws at us through gstreamer's caps negotiation. */
> +static HRESULT media_stream_connect_to_sink(struct media_stream *stream)
> +{
> + GstCaps *source_caps = gst_pad_query_caps(stream->their_src, NULL);
> + const gchar *stream_type;
> +
> + if (!source_caps)
> + return E_FAIL;
> +
> + stream_type = gst_structure_get_name(gst_caps_get_structure(source_caps, 0));
> + gst_caps_unref(source_caps);
> +
> + if (!strcmp(stream_type, "video/x-raw"))
> + {
> + GstElement *videoconvert = gst_element_factory_make("videoconvert", NULL);
> +
> + gst_bin_add(GST_BIN(stream->parent_source->container), videoconvert);
> +
> + stream->my_sink = gst_element_get_static_pad(videoconvert, "sink");
> +
> + if (!gst_element_link(videoconvert, stream->appsink))
> + return E_FAIL;
> +
> + gst_element_sync_state_with_parent(videoconvert);
> + }
> + else
> + {
> + stream->my_sink = gst_element_get_static_pad(stream->appsink, "sink");
> + }
> +
> + if (gst_pad_link(stream->their_src, stream->my_sink) != GST_PAD_LINK_OK)
> + return E_FAIL;
> +
> + return S_OK;
> +}
> +
> static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD stream_id, struct media_stream **out_stream)
> {
> struct media_stream *object = heap_alloc_zero(sizeof(*object));
> @@ -414,8 +451,8 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD
> g_object_set(object->appsink, "sync", FALSE, NULL);
> g_object_set(object->appsink, "max-buffers", 5, NULL);
>
> - object->my_sink = gst_element_get_static_pad(object->appsink, "sink");
> - gst_pad_link(object->their_src, object->my_sink);
> + if (FAILED(hr = media_stream_connect_to_sink(object)))
> + goto fail;
>
> gst_element_sync_state_with_parent(object->appsink);
>
> @@ -435,28 +472,87 @@ static HRESULT media_stream_init_desc(struct media_stream *stream)
> {
> GstCaps *current_caps = gst_pad_get_current_caps(stream->their_src);
> IMFMediaTypeHandler *type_handler;
> + IMFMediaType **stream_types = NULL;
> IMFMediaType *stream_type = NULL;
> + DWORD type_count = 0;
> + const gchar *major_type;
> + unsigned int i;
> HRESULT hr;
>
> - stream_type = mf_media_type_from_caps(current_caps);
> - gst_caps_unref(current_caps);
> - if (!stream_type)
> - return E_FAIL;
> + major_type = gst_structure_get_name(gst_caps_get_structure(current_caps, 0));
> +
> + if (!strcmp(major_type, "video/x-raw"))
> + {
> + /* These are the most common native output types of decoders: https://docs.microsoft.com/en-us/windows/win32/medfound/mft-decoder-expose-output-types-in-native-order */
This line is very long.
> + static const GUID * video_types[] =
"static const GUID *const video_types[]"
> + {
> + &MFVideoFormat_NV12,
> + &MFVideoFormat_YV12,
> + &MFVideoFormat_YUY2,
> + &MFVideoFormat_IYUV,
> + &MFVideoFormat_I420,
> + };
>
> - hr = MFCreateStreamDescriptor(stream->stream_id, 1, &stream_type, &stream->descriptor);
> + IMFMediaType *base_type = mf_media_type_from_caps(current_caps);
> + GUID base_subtype;
>
> - IMFMediaType_Release(stream_type);
> + IMFMediaType_GetGUID(base_type, &MF_MT_SUBTYPE, &base_subtype);
>
> - if (FAILED(hr))
> - return hr;
> + stream_types = heap_alloc( sizeof(IMFMediaType *) * ARRAY_SIZE(video_types) + 1);
>
> - if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(stream->descriptor, &type_handler)))
> - return hr;
> + stream_types[0] = base_type;
> + type_count = 1;
>
> - hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, stream_type);
> + for (i = 0; i < ARRAY_SIZE(video_types); i++)
> + {
> + IMFMediaType *new_type;
>
> - IMFMediaTypeHandler_Release(type_handler);
> + if (IsEqualGUID(&base_subtype, video_types[i]))
> + continue;
>
> + if (FAILED(hr = MFCreateMediaType(&new_type)))
> + goto done;
> + stream_types[type_count++] = new_type;
> +
> + if (FAILED(hr = IMFMediaType_CopyAllItems(base_type, (IMFAttributes *) new_type)))
> + goto done;
> + if (FAILED(hr = IMFMediaType_SetGUID(new_type, &MF_MT_SUBTYPE, video_types[i])))
> + goto done;
> + }
> + }
> + else
> + {
> + stream_type = mf_media_type_from_caps(current_caps);
> + if (stream_type)
> + {
> + stream_types = &stream_type;
> + type_count = 1;
> + }
> + }
> +
> + if (!type_count)
> + {
> + ERR("Failed to establish an IMFMediaType from any of the possible stream caps!\n");
> + return E_FAIL;
> + }
> +
> + if (FAILED(hr = MFCreateStreamDescriptor(stream->stream_id, type_count, stream_types, &stream->descriptor)))
> + goto done;
> +
> + if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(stream->descriptor, &type_handler)))
> + goto done;
> +
> + if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, stream_types[0])))
> + goto done;
> +
> +done:
> + gst_caps_unref(current_caps);
> + if (type_handler)
> + IMFMediaTypeHandler_Release(type_handler);
> + for (i = 0; i < type_count; i++)
> + IMFMediaType_Release(stream_types[i]);
> + if (stream_types != &stream_type)
> + heap_free(stream_types);
> return hr;
> }
>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 484 bytes
Desc: OpenPGP digital signature
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20201006/19751f40/attachment.sig>
More information about the wine-devel
mailing list