Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/mfplat.c | 149 +++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 60b38a48f5a..07556802a51 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -57,6 +57,7 @@ extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) DECLSPEC_HIDDEN; +GstCaps *caps_from_mf_media_type(IMFMediaType *type) DECLSPEC_HIDDEN;
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index 2e8b0978648..9aa17ad00ab 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -601,3 +601,152 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
return media_type; } + +GstCaps *caps_from_mf_media_type(IMFMediaType *type) +{ + GUID major_type; + GUID subtype; + GstCaps *output = NULL; + + if (FAILED(IMFMediaType_GetMajorType(type, &major_type))) + return NULL; + if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) + return NULL; + + if (IsEqualGUID(&major_type, &MFMediaType_Video)) + { + UINT64 frame_rate = 0, frame_size = 0; + DWORD width, height, framerate_num, framerate_den; + UINT32 unused; + + if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))) + return NULL; + width = frame_size >> 32; + height = frame_size; + if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate))) + { + frame_rate = TRUE; + framerate_num = 0; + framerate_den = 1; + } + else + { + framerate_num = frame_rate >> 32; + framerate_den = frame_rate; + } + + /* Check if type is uncompressed */ + if (SUCCEEDED(MFCalculateImageSize(&subtype, 100, 100, &unused))) + { + GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; + unsigned int i; + + output = gst_caps_new_empty_simple("video/x-raw"); + + for (i = 0; i < ARRAY_SIZE(uncompressed_video_formats); i++) + { + if (IsEqualGUID(uncompressed_video_formats[i].subtype, &subtype)) + { + format = uncompressed_video_formats[i].format; + break; + } + } + + if (format == GST_VIDEO_FORMAT_UNKNOWN) + { + format = gst_video_format_from_fourcc(subtype.Data1); + } + + if (format == GST_VIDEO_FORMAT_UNKNOWN) + { + FIXME("Unrecognized format %s\n", debugstr_guid(&subtype)); + return NULL; + } + else + { + GstVideoInfo info; + + gst_video_info_set_format(&info, format, width, height); + output = gst_video_info_to_caps(&info); + } + + } + else { + FIXME("Unrecognized subtype %s\n", debugstr_guid(&subtype)); + return NULL; + } + + + if (frame_size) + { + gst_caps_set_simple(output, "width", G_TYPE_INT, width, NULL); + gst_caps_set_simple(output, "height", G_TYPE_INT, height, NULL); + } + if (frame_rate) + gst_caps_set_simple(output, "framerate", GST_TYPE_FRACTION, framerate_num, framerate_den, NULL); + return output; + } + else if (IsEqualGUID(&major_type, &MFMediaType_Audio)) + { + DWORD rate, channels, channel_mask, bitrate; + + if (IsEqualGUID(&subtype, &MFAudioFormat_Float)) + { + output = gst_caps_new_empty_simple("audio/x-raw"); + + gst_caps_set_simple(output, "format", G_TYPE_STRING, "F32LE", NULL); + gst_caps_set_simple(output, "layout", G_TYPE_STRING, "interleaved", NULL); + } + else if (IsEqualGUID(&subtype, &MFAudioFormat_PCM)) + { + DWORD bits_per_sample; + + if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &bits_per_sample))) + { + char format[6]; + char type; + + type = bits_per_sample > 8 ? 'S' : 'U'; + + output = gst_caps_new_empty_simple("audio/x-raw"); + + sprintf(format, "%c%u%s", type, bits_per_sample, bits_per_sample > 8 ? "LE" : ""); + + gst_caps_set_simple(output, "format", G_TYPE_STRING, format, NULL); + } + else + { + ERR("Bits per sample not set.\n"); + return NULL; + } + } + else + { + FIXME("Unrecognized subtype %s\n", debugstr_guid(&subtype)); + return NULL; + } + + if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate))) + { + gst_caps_set_simple(output, "rate", G_TYPE_INT, rate, NULL); + } + if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels))) + { + gst_caps_set_simple(output, "channels", G_TYPE_INT, channels, NULL); + } + if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, &channel_mask))) + { + gst_caps_set_simple(output, "channel-mask", GST_TYPE_BITMASK, (guint64) channel_mask, NULL); + } + + if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AVG_BITRATE, &bitrate))) + { + gst_caps_set_simple(output, "bitrate", G_TYPE_INT, bitrate, NULL); + } + + return output; + } + + FIXME("Unrecognized major type %s\n", debugstr_guid(&major_type)); + return NULL; +}