Needed for the mfreadwrite pipelines.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/h264_decoder.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index bf691a2e25c..b4dca268790 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -392,27 +392,12 @@ static HRESULT WINAPI transform_AddInputStreams(IMFTransform *iface, DWORD strea static HRESULT WINAPI transform_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, IMFMediaType **type) { - IMFMediaType *media_type; - const GUID *subtype; - HRESULT hr; - TRACE("iface %p, id %#lx, index %#lx, type %p.\n", iface, id, index, type);
*type = NULL; - if (index >= ARRAY_SIZE(h264_decoder_input_types)) return MF_E_NO_MORE_TYPES; - subtype = h264_decoder_input_types[index]; - - if (FAILED(hr = MFCreateMediaType(&media_type))) - return hr; - - if (SUCCEEDED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video)) && - SUCCEEDED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, subtype))) - IMFMediaType_AddRef((*type = media_type)); - - IMFMediaType_Release(media_type); - return hr; + return MFCreateVideoMediaTypeFromSubtype(h264_decoder_input_types[index], (IMFVideoMediaType **)type); }
static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWORD id,
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/h264_decoder.c | 122 ++++++++++++++---------------- 1 file changed, 55 insertions(+), 67 deletions(-)
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index b4dca268790..68922fbc82e 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -116,102 +116,112 @@ static HRESULT try_create_wg_transform(struct h264_decoder *decoder) return S_OK; }
-static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType *media_type) +static HRESULT create_output_media_type(struct h264_decoder *decoder, const GUID *subtype, + IMFMediaType **media_type) { IMFMediaType *default_type = decoder->output_type; + IMFVideoMediaType *video_type; UINT32 value, width, height; MFVideoArea aperture; UINT64 ratio; - GUID subtype; HRESULT hr;
- if (FAILED(hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &subtype))) + if (FAILED(hr = MFCreateVideoMediaTypeFromSubtype(subtype, &video_type))) return hr;
- if (FAILED(hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &ratio))) + if (FAILED(IMFVideoMediaType_GetUINT64(video_type, &MF_MT_FRAME_SIZE, &ratio))) { if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, &ratio))) ratio = (UINT64)1920 << 32 | 1080; - if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ratio))) - return hr; + if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, ratio))) + goto done; } width = ratio >> 32; height = ratio;
- if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_FRAME_RATE, NULL))) + if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_FRAME_RATE, NULL))) { if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_RATE, &ratio))) ratio = (UINT64)30000 << 32 | 1001; - if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, ratio))) - return hr; + if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_FRAME_RATE, ratio))) + goto done; }
- if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_PIXEL_ASPECT_RATIO, NULL))) + if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_PIXEL_ASPECT_RATIO, NULL))) { if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio))) ratio = (UINT64)1 << 32 | 1; - if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, ratio))) - return hr; + if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_PIXEL_ASPECT_RATIO, ratio))) + goto done; }
- if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_SAMPLE_SIZE, NULL))) + if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_SAMPLE_SIZE, NULL))) { - if (FAILED(hr = MFCalculateImageSize(&subtype, width, height, &value))) - return hr; - if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, value))) - return hr; + if (FAILED(hr = MFCalculateImageSize(subtype, width, height, &value))) + goto done; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_SAMPLE_SIZE, value))) + goto done; }
- if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_DEFAULT_STRIDE, NULL))) + if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_DEFAULT_STRIDE, NULL))) { - if (FAILED(hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, width, (LONG *)&value))) - return hr; - if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, value))) - return hr; + if (FAILED(hr = MFGetStrideForBitmapInfoHeader(subtype->Data1, width, (LONG *)&value))) + goto done; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_DEFAULT_STRIDE, value))) + goto done; }
- if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_INTERLACE_MODE, NULL))) + if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_INTERLACE_MODE, NULL))) { - if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_INTERLACE_MODE, &value))) + if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_INTERLACE_MODE, &value))) value = MFVideoInterlace_MixedInterlaceOrProgressive; - if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_INTERLACE_MODE, value))) - return hr; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_INTERLACE_MODE, value))) + goto done; }
- if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, NULL))) + if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, NULL))) { - if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value))) + if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value))) value = 1; - if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, value))) - return hr; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, value))) + goto done; }
- if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_VIDEO_ROTATION, NULL))) + if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_VIDEO_ROTATION, NULL))) { - if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_VIDEO_ROTATION, &value))) + if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_VIDEO_ROTATION, &value))) value = 0; - if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_VIDEO_ROTATION, value))) - return hr; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_VIDEO_ROTATION, value))) + goto done; }
- if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_FIXED_SIZE_SAMPLES, NULL))) + if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_FIXED_SIZE_SAMPLES, NULL))) { - if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_FIXED_SIZE_SAMPLES, &value))) + if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_FIXED_SIZE_SAMPLES, &value))) value = 1; - if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, value))) - return hr; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_FIXED_SIZE_SAMPLES, value))) + goto done; }
- if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, NULL)) - && SUCCEEDED(hr = IMFMediaType_GetBlob(decoder->stream_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, + if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, NULL)) + && SUCCEEDED(IMFMediaType_GetBlob(decoder->stream_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&aperture, sizeof(aperture), &value))) { - if (FAILED(hr = IMFMediaType_SetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, + if (FAILED(hr = IMFVideoMediaType_SetBlob(video_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&aperture, sizeof(aperture)))) - return hr; + goto done; }
- return S_OK; +done: + if (SUCCEEDED(hr)) + *media_type = (IMFMediaType *)video_type; + else + { + IMFVideoMediaType_Release(video_type); + *media_type = NULL; + } + + return hr; }
static HRESULT init_allocator(struct h264_decoder *decoder) @@ -404,37 +414,15 @@ static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWOR DWORD index, IMFMediaType **type) { struct h264_decoder *decoder = impl_from_IMFTransform(iface); - IMFMediaType *media_type; - const GUID *output_type; - HRESULT hr;
TRACE("iface %p, id %#lx, index %#lx, type %p.\n", iface, id, index, type);
+ *type = NULL; if (!decoder->input_type) return MF_E_TRANSFORM_TYPE_NOT_SET; - - *type = NULL; - if (index >= ARRAY_SIZE(h264_decoder_output_types)) return MF_E_NO_MORE_TYPES; - output_type = h264_decoder_output_types[index]; - - if (FAILED(hr = MFCreateMediaType(&media_type))) - return hr; - - if (FAILED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video))) - goto done; - if (FAILED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, output_type))) - goto done; - - hr = fill_output_media_type(decoder, media_type); - -done: - if (SUCCEEDED(hr)) - IMFMediaType_AddRef((*type = media_type)); - - IMFMediaType_Release(media_type); - return hr; + return create_output_media_type(decoder, h264_decoder_output_types[index], type); }
static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/h264_decoder.c | 118 ++++++++++++------------------ 1 file changed, 45 insertions(+), 73 deletions(-)
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 68922fbc82e..59cb389fc68 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -129,82 +129,54 @@ static HRESULT create_output_media_type(struct h264_decoder *decoder, const GUID if (FAILED(hr = MFCreateVideoMediaTypeFromSubtype(subtype, &video_type))) return hr;
- if (FAILED(IMFVideoMediaType_GetUINT64(video_type, &MF_MT_FRAME_SIZE, &ratio))) - { - if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, &ratio))) - ratio = (UINT64)1920 << 32 | 1080; - if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, ratio))) - goto done; - } + if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, &ratio))) + ratio = (UINT64)1920 << 32 | 1080; + if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, ratio))) + goto done; width = ratio >> 32; height = ratio;
- if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_FRAME_RATE, NULL))) - { - if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_RATE, &ratio))) - ratio = (UINT64)30000 << 32 | 1001; - if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_FRAME_RATE, ratio))) - goto done; - } - - if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_PIXEL_ASPECT_RATIO, NULL))) - { - if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio))) - ratio = (UINT64)1 << 32 | 1; - if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_PIXEL_ASPECT_RATIO, ratio))) - goto done; - } - - if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_SAMPLE_SIZE, NULL))) - { - if (FAILED(hr = MFCalculateImageSize(subtype, width, height, &value))) - goto done; - if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_SAMPLE_SIZE, value))) - goto done; - } - - if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_DEFAULT_STRIDE, NULL))) - { - if (FAILED(hr = MFGetStrideForBitmapInfoHeader(subtype->Data1, width, (LONG *)&value))) - goto done; - if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_DEFAULT_STRIDE, value))) - goto done; - } - - if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_INTERLACE_MODE, NULL))) - { - if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_INTERLACE_MODE, &value))) - value = MFVideoInterlace_MixedInterlaceOrProgressive; - if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_INTERLACE_MODE, value))) - goto done; - } - - if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, NULL))) - { - if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value))) - value = 1; - if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, value))) - goto done; - } - - if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_VIDEO_ROTATION, NULL))) - { - if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_VIDEO_ROTATION, &value))) - value = 0; - if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_VIDEO_ROTATION, value))) - goto done; - } - - if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_FIXED_SIZE_SAMPLES, NULL))) - { - if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_FIXED_SIZE_SAMPLES, &value))) - value = 1; - if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_FIXED_SIZE_SAMPLES, value))) - goto done; - } - - if (FAILED(IMFVideoMediaType_GetItem(video_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, NULL)) - && SUCCEEDED(IMFMediaType_GetBlob(decoder->stream_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, + if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_RATE, &ratio))) + ratio = (UINT64)30000 << 32 | 1001; + if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_FRAME_RATE, ratio))) + goto done; + + if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio))) + ratio = (UINT64)1 << 32 | 1; + if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_PIXEL_ASPECT_RATIO, ratio))) + goto done; + + if (FAILED(hr = MFCalculateImageSize(subtype, width, height, &value))) + goto done; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_SAMPLE_SIZE, value))) + goto done; + + if (FAILED(hr = MFGetStrideForBitmapInfoHeader(subtype->Data1, width, (LONG *)&value))) + goto done; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_DEFAULT_STRIDE, value))) + goto done; + + if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_INTERLACE_MODE, &value))) + value = MFVideoInterlace_MixedInterlaceOrProgressive; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_INTERLACE_MODE, value))) + goto done; + + if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value))) + value = 1; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, value))) + goto done; + + if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_VIDEO_ROTATION, &value))) + value = 0; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_VIDEO_ROTATION, value))) + goto done; + + if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_FIXED_SIZE_SAMPLES, &value))) + value = 1; + if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_FIXED_SIZE_SAMPLES, value))) + goto done; + + if (SUCCEEDED(IMFMediaType_GetBlob(decoder->stream_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&aperture, sizeof(aperture), &value))) { if (FAILED(hr = IMFVideoMediaType_SetBlob(video_type, &MF_MT_MINIMUM_DISPLAY_APERTURE,
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/h264_decoder.c | 108 ++++++++++++++++++------------ 1 file changed, 67 insertions(+), 41 deletions(-)
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 59cb389fc68..e4ac11f98b8 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -33,14 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat); WINE_DECLARE_DEBUG_CHANNEL(winediag);
-#define ALIGN_SIZE(size, alignment) (((size) + (alignment)) & ~((alignment))) - -static const GUID *const h264_decoder_input_types[] = -{ - &MFVideoFormat_H264, - &MFVideoFormat_H264_ES, -}; -static const GUID *const h264_decoder_output_types[] = +static const GUID *const video_decoder_output_types[] = { &MFVideoFormat_NV12, &MFVideoFormat_YV12, @@ -57,6 +50,11 @@ struct h264_decoder IMFAttributes *attributes; IMFAttributes *output_attributes;
+ UINT input_type_count; + const GUID *const *input_types; + UINT output_type_count; + const GUID *const *output_types; + UINT64 sample_time; IMFMediaType *input_type; MFT_INPUT_STREAM_INFO input_info; @@ -374,12 +372,14 @@ static HRESULT WINAPI transform_AddInputStreams(IMFTransform *iface, DWORD strea static HRESULT WINAPI transform_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, IMFMediaType **type) { + struct h264_decoder *decoder = impl_from_IMFTransform(iface); + TRACE("iface %p, id %#lx, index %#lx, type %p.\n", iface, id, index, type);
*type = NULL; - if (index >= ARRAY_SIZE(h264_decoder_input_types)) + if (index >= decoder->input_type_count) return MF_E_NO_MORE_TYPES; - return MFCreateVideoMediaTypeFromSubtype(h264_decoder_input_types[index], (IMFVideoMediaType **)type); + return MFCreateVideoMediaTypeFromSubtype(decoder->input_types[index], (IMFVideoMediaType **)type); }
static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWORD id, @@ -392,9 +392,9 @@ static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWOR *type = NULL; if (!decoder->input_type) return MF_E_TRANSFORM_TYPE_NOT_SET; - if (index >= ARRAY_SIZE(h264_decoder_output_types)) + if (index >= decoder->output_type_count) return MF_E_NO_MORE_TYPES; - return create_output_media_type(decoder, h264_decoder_output_types[index], type); + return create_output_media_type(decoder, decoder->output_types[index], type); }
static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) @@ -414,10 +414,10 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM if (!IsEqualGUID(&major, &MFMediaType_Video)) return MF_E_INVALIDMEDIATYPE;
- for (i = 0; i < ARRAY_SIZE(h264_decoder_input_types); ++i) - if (IsEqualGUID(&subtype, h264_decoder_input_types[i])) + for (i = 0; i < decoder->input_type_count; ++i) + if (IsEqualGUID(&subtype, decoder->input_types[i])) break; - if (i == ARRAY_SIZE(h264_decoder_input_types)) + if (i == decoder->input_type_count) return MF_E_INVALIDMEDIATYPE; if (flags & MFT_SET_TYPE_TEST_ONLY) return S_OK; @@ -462,10 +462,10 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF if (!IsEqualGUID(&major, &MFMediaType_Video)) return MF_E_INVALIDMEDIATYPE;
- for (i = 0; i < ARRAY_SIZE(h264_decoder_output_types); ++i) - if (IsEqualGUID(&subtype, h264_decoder_output_types[i])) + for (i = 0; i < decoder->output_type_count; ++i) + if (IsEqualGUID(&subtype, decoder->output_types[i])) break; - if (i == ARRAY_SIZE(h264_decoder_output_types)) + if (i == decoder->output_type_count) return MF_E_INVALIDMEDIATYPE;
if (FAILED(hr = IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))) @@ -777,39 +777,23 @@ static const IMFTransformVtbl transform_vtbl = transform_ProcessOutput, };
-HRESULT h264_decoder_create(REFIID riid, void **ret) +static HRESULT video_decoder_create_with_types(const GUID *const *input_types, UINT input_type_count, + const GUID *const *output_types, UINT output_type_count, IMFTransform **ret) { - static const struct wg_format output_format = - { - .major_type = WG_MAJOR_TYPE_VIDEO, - .u.video = - { - .format = WG_VIDEO_FORMAT_I420, - .width = 1920, - .height = 1080, - }, - }; - static const struct wg_format input_format = {.major_type = WG_MAJOR_TYPE_VIDEO_H264}; - struct wg_transform_attrs attrs = {0}; - wg_transform_t transform; struct h264_decoder *decoder; HRESULT hr;
- TRACE("riid %s, ret %p.\n", debugstr_guid(riid), ret); - - if (!(transform = wg_transform_create(&input_format, &output_format, &attrs))) - { - ERR_(winediag)("GStreamer doesn't support H.264 decoding, please install appropriate plugins\n"); - return E_FAIL; - } - wg_transform_destroy(transform); - if (!(decoder = calloc(1, sizeof(*decoder)))) return E_OUTOFMEMORY;
decoder->IMFTransform_iface.lpVtbl = &transform_vtbl; decoder->refcount = 1;
+ decoder->input_type_count = input_type_count; + decoder->input_types = input_types; + decoder->output_type_count = output_type_count; + decoder->output_types = output_types; + decoder->input_info.dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE; decoder->input_info.cbSize = 0x1000; @@ -855,3 +839,45 @@ failed: free(decoder); return hr; } + +static const GUID *const h264_decoder_input_types[] = +{ + &MFVideoFormat_H264, + &MFVideoFormat_H264_ES, +}; + +HRESULT h264_decoder_create(REFIID riid, void **out) +{ + static const struct wg_format output_format = + { + .major_type = WG_MAJOR_TYPE_VIDEO, + .u.video = + { + .format = WG_VIDEO_FORMAT_I420, + .width = 1920, + .height = 1080, + }, + }; + static const struct wg_format input_format = {.major_type = WG_MAJOR_TYPE_VIDEO_H264}; + struct wg_transform_attrs attrs = {0}; + wg_transform_t transform; + IMFTransform *iface; + HRESULT hr; + + TRACE("riid %s, out %p.\n", debugstr_guid(riid), out); + + if (!(transform = wg_transform_create(&input_format, &output_format, &attrs))) + { + ERR_(winediag)("GStreamer doesn't support H.264 decoding, please install appropriate plugins\n"); + return E_FAIL; + } + wg_transform_destroy(transform); + + if (FAILED(hr = video_decoder_create_with_types(h264_decoder_input_types, ARRAY_SIZE(h264_decoder_input_types), + video_decoder_output_types, ARRAY_SIZE(video_decoder_output_types), &iface))) + return hr; + + hr = IMFTransform_QueryInterface(iface, riid, out); + IMFTransform_Release(iface); + return hr; +}
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/h264_decoder.c | 33 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index e4ac11f98b8..fae4ede3b54 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -115,9 +115,9 @@ static HRESULT try_create_wg_transform(struct h264_decoder *decoder) }
static HRESULT create_output_media_type(struct h264_decoder *decoder, const GUID *subtype, - IMFMediaType **media_type) + IMFMediaType *output_type, IMFMediaType **media_type) { - IMFMediaType *default_type = decoder->output_type; + IMFMediaType *default_type = decoder->output_type, *stream_type = output_type ? output_type : decoder->stream_type; IMFVideoMediaType *video_type; UINT32 value, width, height; MFVideoArea aperture; @@ -127,31 +127,31 @@ static HRESULT create_output_media_type(struct h264_decoder *decoder, const GUID if (FAILED(hr = MFCreateVideoMediaTypeFromSubtype(subtype, &video_type))) return hr;
- if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, &ratio))) + if (FAILED(IMFMediaType_GetUINT64(stream_type, &MF_MT_FRAME_SIZE, &ratio))) ratio = (UINT64)1920 << 32 | 1080; if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, ratio))) goto done; width = ratio >> 32; height = ratio;
- if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_RATE, &ratio))) + if (FAILED(IMFMediaType_GetUINT64(stream_type, &MF_MT_FRAME_RATE, &ratio))) ratio = (UINT64)30000 << 32 | 1001; if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_FRAME_RATE, ratio))) goto done;
- if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio))) + if (FAILED(IMFMediaType_GetUINT64(stream_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio))) ratio = (UINT64)1 << 32 | 1; if (FAILED(hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_PIXEL_ASPECT_RATIO, ratio))) goto done;
- if (FAILED(hr = MFCalculateImageSize(subtype, width, height, &value))) - goto done; - if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_SAMPLE_SIZE, value))) + if (!output_type || FAILED(IMFMediaType_GetUINT32(output_type, &MF_MT_SAMPLE_SIZE, &value))) + hr = MFCalculateImageSize(subtype, width, height, &value); + if (FAILED(hr) || FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_SAMPLE_SIZE, value))) goto done;
- if (FAILED(hr = MFGetStrideForBitmapInfoHeader(subtype->Data1, width, (LONG *)&value))) - goto done; - if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_DEFAULT_STRIDE, value))) + if (!output_type || FAILED(IMFMediaType_GetUINT32(output_type, &MF_MT_DEFAULT_STRIDE, &value))) + hr = MFGetStrideForBitmapInfoHeader(subtype->Data1, width, (LONG *)&value); + if (FAILED(hr) || FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_DEFAULT_STRIDE, value))) goto done;
if (!default_type || FAILED(IMFMediaType_GetUINT32(default_type, &MF_MT_INTERLACE_MODE, &value))) @@ -174,7 +174,7 @@ static HRESULT create_output_media_type(struct h264_decoder *decoder, const GUID if (FAILED(hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_FIXED_SIZE_SAMPLES, value))) goto done;
- if (SUCCEEDED(IMFMediaType_GetBlob(decoder->stream_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, + if (SUCCEEDED(IMFMediaType_GetBlob(stream_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&aperture, sizeof(aperture), &value))) { if (FAILED(hr = IMFVideoMediaType_SetBlob(video_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, @@ -394,7 +394,7 @@ static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWOR return MF_E_TRANSFORM_TYPE_NOT_SET; if (index >= decoder->output_type_count) return MF_E_NO_MORE_TYPES; - return create_output_media_type(decoder, decoder->output_types[index], type); + return create_output_media_type(decoder, decoder->output_types[index], NULL, type); }
static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) @@ -521,17 +521,16 @@ static HRESULT WINAPI transform_GetInputCurrentType(IMFTransform *iface, DWORD i static HRESULT WINAPI transform_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) { struct h264_decoder *decoder = impl_from_IMFTransform(iface); + GUID subtype; HRESULT hr;
TRACE("iface %p, id %#lx, type %p\n", iface, id, type);
if (!decoder->output_type) return MF_E_TRANSFORM_TYPE_NOT_SET; - - if (FAILED(hr = MFCreateMediaType(type))) + if (FAILED(hr = IMFMediaType_GetGUID(decoder->output_type, &MF_MT_SUBTYPE, &subtype))) return hr; - - return IMFMediaType_CopyAllItems(decoder->output_type, (IMFAttributes *)*type); + return create_output_media_type(decoder, &subtype, decoder->output_type, type); }
static HRESULT WINAPI transform_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
The oleaut32 failure is unrelated and comes from https://gitlab.winehq.org/wine/wine/-/merge_requests/5080.
The mf:mf failure also doesn't seem related - some functions returns S_OK when we expect MF_E_SHUTDOWN - and I believe it is instead a random behavior caused by a threadpool assert which started to happen since https://gitlab.winehq.org/wine/wine/-/merge_requests/3572
This merge request was approved by Zebediah Figura.